Garbage Collector looping when I use socket

2020-07-23 09:32发布

问题:

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

回答1:

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.



回答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.



回答3:

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.