novoda / merlin

Observes network connection status & gives callbacks
Other
543 stars 79 forks source link

Fatal Exception: java.util.ConcurrentModificationException #168

Closed vinceglb closed 5 years ago

vinceglb commented 6 years ago

Problem

Fatal Exception: java.util.ConcurrentModificationException

There is my Crashlytics trace:

Android version : 5.1 Phone : GI-I9500_TMMARS

java.util.ArrayList$ArrayListIterator.next (ArrayList.java:573) com.novoda.merlin.registerable.connection.ConnectCallbackManager.onConnect (Unknown Source) com.novoda.merlin.service.ConnectivityChangesForwarder$1.onSuccess (Unknown Source) com.novoda.merlin.service.PingTask.doInBackground (Unknown Source) com.novoda.merlin.service.PingTask.onPostExecute (Unknown Source) android.os.AsyncTask.finish (AsyncTask.java:636) android.os.AsyncTask.access$500 (AsyncTask.java:177) android.os.AsyncTask$InternalHandler.handleMessage (AsyncTask.java:653) android.os.Handler.dispatchMessage (Handler.java:102) android.os.Looper.loop (Looper.java:135) android.app.ActivityThread.main (ActivityThread.java:5263) java.lang.reflect.Method.invoke (Method.java) java.lang.reflect.Method.invoke (Method.java:372) com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:903) com.android.internal.os.ZygoteInit.main (ZygoteInit.java:698)

Potential Solution

I have no idea... 🤕

Impact

I followed exactly your tutorial for setup merlin. Do you have any idea why "ConcurrentModificationException" ?

Thanks 👍

niltsiar commented 6 years ago

Just from that trace I think the problem may be that you are registering some Connectable while some network change is being notified to the ones previously registered. Could you provide some example to look further?

vinceglb commented 6 years ago

My class using Merlin :

public class ManageInternet implements LoaderManager.LoaderCallbacks<Boolean>,
        Connectable, Disconnectable {

    // ...

    private final Merlin merlin;
    private final MerlinsBeard merlinsBeard;

    // ...

    public ManageInternet(@NonNull MyActivity activity) {

        // INTERNET Merlin
        this.merlin = new Merlin.Builder()
                .withConnectableCallbacks()
                .withDisconnectableCallbacks()
                .build(vinceActivity2);
        this.merlin.registerConnectable(this);
        this.merlin.registerDisconnectable(this);
        this.merlinsBeard = MerlinsBeard.from(activity);

       // ...

    }

    // ...

   public void bindMerlin() {
        merlin.bind();
        if (merlinsBeard.isConnected())
            onConnect();
        else
            onDisconnect();
    }

    public void unbindMerlin() {
        merlin.unbind();
        internetStateChanged = true;
    }

   ...

}

In my activity class :

public abstract class MyActivity extends AppCompatActivity {

    // ...

    private ManageInternet mi;

    @Override
    @CallSuper
    protected void onCreate(@Nullable Bundle savedInstanceState) {

        // ...

        // INTERNET
        mi = new ManageInternet (this);

        // ...

    }

    @Override
    @CallSuper
    protected void onResume() {

        super.onResume();

        // INTERNET (désabonne dans le onPause())
        gl.bindMerlin();

    }

    @Override
    @CallSuper
    protected void onPause() {

        // INTERNET
        gl.unbindMerlin();

        super.onPause();

    }

}

"MyActivity" is the abstract class that all my other activities depend. "ManageInternet" helps to load data from internet when the connection is available.

This error is not critical, I just had one crash few days ago on one of my users. On firebase, crashlytics doest not give me informations about where my code launched your code. I will give you more informations in the future if this error raise again.

Mecharyry commented 6 years ago

Given that it comes from a PingTask it seems unlikely that this code is at fault. As you said @EBfVince you have just copied the demo. It seems that this could happen should a ping task callback when attempting to clear the registrations when unbinding merlin.

niltsiar commented 6 years ago

Yes, it seems that the underlying connectable collection could be modified while notifying those Connectable and it causes the mentioned Exception. I've tried to create a test for such condition and a possible fix for that.

niltsiar commented 5 years ago

This should be already fixed in #183