2

I'm including a socket in my project and it's working well. My server received my request and my app received the answer. Almost everything rights except for the garbage collector start looping and didn't stop.

I killed all the intents before (including the intent who called the socket), I tried the socket.disconnect, I closed my application (and the GC still running) but didn't work.

The GC just stops if I Run my app again or force stop in the configurations.

Where is my code and the Log

public class ListaRestaurantesActivity extends Activity implements NumberPicker.OnValueChangeListener {

    private static Context context;
    private static Dialog dialog;
    private static NumberPicker numberPickerDialog;
    private Button botaoOkDialog;
    private Button botaoCancelDialog;
    private ListView lv_telaListaRestaurante_Lista;
    private ListaRestaurantesAdapter lra;
    private List<ListaRestauranteTO> listaRestauranteTO;

    public static void entraMesaAprovado(String idRestaurante) {
        Intent mesa = new Intent(context, SelectedRestauranteActivity.class);
        mesa.putExtra("numeroMesa", String.valueOf(numberPickerDialog.getValue()));
        mesa.putExtra("idRestaurante", idRestaurante);
        context.startActivity(mesa);
        dialog.dismiss();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lista_restaurante);

        lv_telaListaRestaurante_Lista = (ListView) findViewById(R.id.lv_telaListaRestaurante_Lista);

        dialog = new Dialog(ListaRestaurantesActivity.this);
        dialog.setContentView(R.layout.view_alert_dialog);
        dialog.setTitle(R.string.txt_alertDialog_Cabecalho);

        numberPickerDialog = (NumberPicker) dialog.findViewById(R.id.np_viewAlertDialog_NumeroMesa);
        botaoOkDialog = (Button) dialog.findViewById(R.id.bt_viewAlertDialog_OK);
        botaoCancelDialog = (Button) dialog.findViewById(R.id.bt_viewAlertDialog_Cancel);

        new AsyncTask<Context, Void, Void>() {
            private UtilWS ws;
            private JsonElement jsonElement;
            private Gson gson = new Gson();
            private Type type = new TypeToken<ListaRestauranteTO>() { }.getType();

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                ws = new UtilWS();
                listaRestauranteTO = new ArrayList<ListaRestauranteTO>();
            }

            @Override
            protected Void doInBackground(Context... params) {
                context = params[0];
                String[] postResult = ws.post(UtilWS.URL_LISTA_LOCAIS, "");
                if (postResult[0].equals("200")) {
                    JsonObject temp = new JsonParser().parse(postResult[1]).getAsJsonObject();
                    JsonArray jsonArray = temp.getAsJsonArray("restaurantes");
                    for (int i = 0; i < jsonArray.size(); i++) {
                        jsonElement = jsonArray.get(i);
                        listaRestauranteTO.add((ListaRestauranteTO) gson.fromJson(jsonElement, type));
                    }
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void aVoid) {
                super.onPostExecute(aVoid);
                lra = new ListaRestaurantesAdapter(context, listaRestauranteTO);
                lv_telaListaRestaurante_Lista.setAdapter(lra);
            }
        }.execute(this);

        lv_telaListaRestaurante_Lista.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
                Log.i("Contents", " = " + view.getTag());
                show((String) view.getTag());
            }
        });
    }

    public void show(final String idRestaurante)
    {
        String[] listaMesas = null;

        for (int i = 0; i < listaRestauranteTO.size(); i++) {
            for (int j = 0; j < listaRestauranteTO.get(i).getMesas().size(); j++) {
                if (listaRestauranteTO.get(i).getMesas().get(j).getRestaurante_id().equals(idRestaurante)) {
                    if (listaMesas == null) {
                        listaMesas = new String[listaRestauranteTO.get(i).getMesas().size()];
                    }
                    listaMesas[j] = listaRestauranteTO.get(i).getMesas().get(j).getNumero();
                } else {
                    j = listaRestauranteTO.get(i).getMesas().size() + 1;
                }
            }
        }
        numberPickerDialog.setMinValue(1);
        numberPickerDialog.setMaxValue(listaMesas.length);
        numberPickerDialog.setDisplayedValues(listaMesas);
        numberPickerDialog.setWrapSelectorWheel(false);
        numberPickerDialog.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
        numberPickerDialog.setOnValueChangedListener(this);
        botaoOkDialog.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new AsyncTask<Void, Void, Void>() {

                    @Override
                    protected Void doInBackground(Void... params) {
                        new ReceiveCallback(context, String.valueOf(numberPickerDialog.getValue()), idRestaurante);
                        return null;
                    }
                }.execute();
            }
        });
        botaoCancelDialog.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
        dialog.show();
    }

    @Override
    public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
    }
}

class ReceiveCallback implements IOCallback {
    private SocketIO socket = new SocketIO();
    private FBSessionsManager fbSessionsManager;
    private Context context;
    private String idRestaurante;

    public ReceiveCallback(Context context, String mesaNumero, String idRestaurente) {
        this.context = context;
        idRestaurante = idRestaurente;
        fbSessionsManager = new FBSessionsManager(this.context);
        try {
            socket.connect("http://192.168.25.5:3001/", this);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        try {
            socket.emit("solicita-mesa", new JSONObject().put("userId", fbSessionsManager.getStoredPrivateSession()[1])
                    .put("mesaNumero", mesaNumero).put("restauranteId", idRestaurente));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onMessage(JSONObject json, IOAcknowledge ack) {
        try {
            Log.i("Server said:" + json.toString(2), ".");
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onMessage(String data, IOAcknowledge ack) {
        Log.i("Server said: " + data, ".");
    }

    @Override
    public void onError(SocketIOException socketIOException) {
        Log.i("an Error occured", ".");
        socketIOException.printStackTrace();
    }

    @Override
    public void onDisconnect() {
        Log.i("Connection terminated.", ".");
    }

    @Override
    public void onConnect() {
        Log.i("Connection established", ".");
        Intent i = new Intent(context, MensagemAguardeActivity.class);
        context.startActivity(i);
    }

    @Override
    public void on(String event, IOAcknowledge ack, Object... args) {
        JSONObject object = (JSONObject) args[0];
        if (event.equals("confirmacao")) {
            try {
                if ((Boolean) object.get("confirmado")) {
                    ListaRestaurantesActivity.entraMesaAprovado(idRestaurante);
                }
                socket.disconnect();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        if (event.equals("remove-prato")) {
        }
    }
}

01-29 12:02:10.161    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 6589K, 30% free 16328K/23076K, paused 1ms+2ms, total 31ms
01-29 12:02:16.341    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 18334K, 60% free 12654K/31144K, paused 1ms+1ms, total 53ms
01-29 12:02:22.471    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 14657K, 60% free 12646K/31144K, paused 1ms+11ms, total 64ms
01-29 12:02:28.591    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 14648K, 54% free 12651K/27460K, paused 1ms+1ms, total 52ms
01-29 12:02:34.731    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 14654K, 54% free 12649K/27464K, paused 11ms+0ms, total 63ms
01-29 12:02:40.841    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 14654K, 54% free 12646K/27464K, paused 1ms+1ms, total 53ms
01-29 12:02:46.991    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 14650K, 54% free 12652K/27464K, paused 1ms+1ms, total 52ms
01-29 12:02:53.091    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 14658K, 54% free 12654K/27468K, paused 1ms+1ms, total 52ms
01-29 12:02:59.221    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 14658K, 54% free 12642K/27468K, paused 1ms+1ms, total 47ms
01-29 12:03:05.591    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 14646K, 54% free 12641K/27468K, paused 12ms+1ms, total 66ms
01-29 12:03:11.781    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 14646K, 54% free 12649K/27456K, paused 12ms+13ms, total 75ms
01-29 12:03:17.951    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 14654K, 54% free 12648K/27464K, paused 1ms+11ms, total 63ms
01-29 12:03:24.071    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 14654K, 54% free 12644K/27464K, paused 11ms+1ms, total 64ms
01-29 12:03:30.191    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 14650K, 54% free 12654K/27460K, paused 1ms+1ms, total 52ms
01-29 12:03:36.331    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 14658K, 54% free 12648K/27468K, paused 12ms+11ms, total 74ms
01-29 12:03:42.471    8994-8996/br.com.timo.xxxx D/dalvikvm﹕ GC_CONCURRENT freed 14650K, 54% free 12642K/27468K, paused 11ms+0ms, total 63ms

What I need to do to stop this GC looping? It's consuming a lot of battery.

Thanks and regards.

UPDATE

I'm using this socket library.

SocketIO Lib

UPDATE 04 FEBRUARY 2014

After some tests, I found a clue. The method socket.disconnect caused the looping in my application and now I'm with another problem.

What should I do? If I execute the method socket.disconnect the GC will run infinitely and if I don't use the socket.disconnect the application will stay with the socket opened and working and will consume a lot of battery.

UPDATE 06 FEBRUARY 2014

I still have not solved this question but I read the issues of SocketIO on Github and I saw a lot of developers with the same error and until today the problem continues.

The link to the issues of SocketIO project is here: Issues Project SocketIO

groff07
  • 2,363
  • 3
  • 32
  • 48
  • 1
    Your problem is not garbage collection. It seems that you have a) a leak and b) due to that (or reason for the former) a running thread somewhere. Edit: Please paste correct code, there is something wrong (e.g. more than 1 `doInBackground`) – zapl Jan 29 '14 at 15:14
  • @zapl This is the correct code. I used the DDMS like the answer of fadden said and I confirmed that I have a Thread running but I don't know where. I will update my post just to complement some informations. Take a look please. Thanks – groff07 Jan 29 '14 at 17:11
  • You must have made a copy paste error. Look at the place of `}.execute();` somewhere inside the `show(final String idRestaurante)` method for example. – zapl Jan 29 '14 at 17:23
  • I looked the classes of the Socket lib and maybe the error it's inside of one of the classes. I found some while codes and synchronized. What you think @zapl? – groff07 Jan 29 '14 at 17:48
  • Unlikely. You are probably using it wrong. – zapl Jan 29 '14 at 17:49
  • Can be. It's my first time using socket. but I just use the socket on this class that I posted. – groff07 Jan 29 '14 at 17:55
  • I created a global SocketIO. I connect and emit what I want on my constructor. And when I receive some answer, I call a method who creates a Intent and call socket.disconnect. There something more that I didn't do? – groff07 Jan 29 '14 at 18:03
  • @zapl...May you help me with this? I opened a chat room to talk. I didn't found the solution. http://chat.stackoverflow.com/rooms/46704/question-about-socket-and-gc – groff07 Feb 03 '14 at 21:10
  • @zapl....Take a look my question, please. I have some new informations. – groff07 Feb 04 '14 at 13:53
  • I don't see where you are wrong because I don't know how SocketIO works / how to cancel it correctly. What I can see is that you store several things in `static` variables which is a very bad idea regarding leaks (it should not cause your problem though). In case you are using Eclipse, go to the DDMS tab, select your app from the left and start method profiling (small arrows to the right with a red dot) and see what happens while your app is active. You can see active threads in there. http://software.intel.com/en-us/articles/performance-debugging-of-android-applications has more info – zapl Feb 04 '14 at 17:45
  • Thanks for the help @zapl. I will try to find the error but I think the best option here is create my own socket. – groff07 Feb 06 '14 at 17:57
  • hey, have you solve the problem yet? do you know why exactly the socket won't close? – Rijdzuan Sampoerna Feb 11 '14 at 00:22
  • @oneitusatu I used the answer that I accepted here. I searched on internet for java-websocket-1.3.0.jar, I downloaded the file and configured my gradle file. That's it! – groff07 Feb 11 '14 at 11:22

3 Answers3

3

I had the same issue in Android when calling the socket.disconnect().

Here is how it was fixed.

Checkout the socket.io-java-client project from https://github.com/Gottox/socket.io-java-client;

Download the Java-WebSocket-1.3.0.jar;

Replace the WebSocket.jar in the lib file of socket.io project with java-websocket-1.3.0.jar;

Use ant to build the socket.io-java-client to jar;

Then replace the socketio.jar with the new one you just build.

Hope this helps.

RiggsFolly
  • 93,638
  • 21
  • 103
  • 149
  • Sadly I am having a already added DEX error while building the android app. If i try to get the latest from github (https://github.com/TooTallNate/Java-WebSocket) -maybe building the jar by myself would suffice- I have build errors due to missing dependencies (the DefaultSSLWebSocketClientFactory class is missing). The jar I am downloading is from here: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.java-websocket%22 – DNax May 21 '14 at 15:36
  • Having the jar not working on my android app, I managed to make the latest version from TooTallNate. I just deleted the references to DefaultSSLWebSocketClientFactory from the WebsocketTransport class. – DNax May 21 '14 at 18:02
  • Hi, its working with http server. When I'm using secure web sockets issue still there. any fix? – Dev Apr 28 '15 at 04:43
2

Use the DDMS Allocation Tracker to figure out what's causing the allocations when it gets into this state. It lets you see stack traces for the last 512 allocations made.

Some info and links are in this post.

Community
  • 1
  • 1
fadden
  • 51,356
  • 5
  • 116
  • 166
  • I used de DDMS and confirmed. There is some thread running after I receive the answer of the socket but I don't know where. – groff07 Jan 29 '14 at 17:38
  • Go to the DDMS Threads screen. You should be able to see which threads are actively running (their user/system times increase) or if there's one rapidly starting and stopping. Double-clicking a thread will get you a recent stack trace. – fadden Jan 29 '14 at 17:44
  • I saw a lot of different stack trace each time I click on the Thread but I didn't see one pointing some line of my classes @fadden. – groff07 Jan 29 '14 at 17:53
0

I face the same issue with Java webSocket 1.0.3 when socket was closed the GC was looping indefinitely. I didn't find any good solution to solve that. Finally a used an alternative library nv-websocket-client https://github.com/TakahikoKawasaki/nv-websocket-client.

Which is pretty good to implement web socket on Android, and simple to used. No more GC problem.

Renaud Boulard
  • 709
  • 6
  • 9