androidandroid-serviceipcandroid-service-bindingbindservice

What happen when the activity crash?


I have a service created like this :

<service
    android:name="com.myFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>

Then I implement the onBind like this:

  private final IBinder mBinder = new LocalBinder();
  private myListener mListener;


  public class LocalBinder extends Binder {
    LocalService getService() {
      return LocalService.this;
    }
  }

  public void setListener(myListener listener) {
    mListener = listener;
  }    

  @Override
  public IBinder onBind(Intent intent) {
    return mBinder;
  } 

  @Override
  public void onMessageReceived(RemoteMessage remoteMessage) {
    if (mListener != null) mListener.onMessageReceived(remoteMessage);  
  }

It is quite simple: the Activity binds to the Service and sets up a listener. When the Service receives a message it simply fires the listener

Now the big question: what happen if the activity crash suddenly? In that case mListener will point to something non-existent, no?

How, before calling mListener.onMessageReceived(remoteMessage), can I check to see if the bound Activity is still alive ?


Solution

  • You can use a WeakReference and DeadObjectException since your Activity seems to be in another app. This will allow you to know if the Activity was garbage collected because your reference will become null and you will not leak.

    private WeakReference<MyListener> mListener;
    

    This is how you store the WeakReference.

    public void setListener(MyListener listener) 
    {
       mListener = new WeakReference<MyListener>(listener);
    }  
    

    This is how you use it.

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) 
    {
        MyListener listener = mListener.get();
    
        if(listener != null)
        {
            try
            {
                listener.onMessageReceived(remoteMessage);  
            }
            catch(DeadObjectException exception)
            {
    
            }
        }
        else
        {
            // Activity was destroyed.
        }
    }