Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with DeadObjectException on killed Service?

I am getting DeadObjectException in my code. Below, I describe my setup, and what I have tried to fix the issue.


A Service S is started from Application A.

Activity B (from another application) communicates with that service using Messenger and IBinder interfaces. This activity is also started from the same service. On a button press inside this activity, I am supposed to send a message back to the service. I frequently get DeadObjectException on button press.

I understand that the most likely cause for this is - system killed and restarted the service, and the activity has old reference to it. Beyond this, I haven't found much information online.

This is what I have tried:

  • I used a startForeground() in service, and I could see that the service was running (notification in notification area) continuously. I still got the exception.
  • On a system reboot, I do not get this exception for a while.
  • The exception is intermittent. I do not have a 100% repro. However, in the following scenario, I always get the exception:
    1. Start app A (thi also start the service S).
    2. Start activity B, everything works fine.
    3. Restart the service by redeploying app A.
    4. Navigate to activity B. The exception happens.
    5. At this point, if I restart activity B, the exception disappears.
  • This led me to conclude that if I made sure that the activity B is fresh every time the service starts, this exception would disappear. I then tried to deliver a murdering intent to activity B, prior to starting it. (Activity has a BroadcastReceiver, and calls finish() in onReceive()). The problem is, if the activity pauses, Intents are not delivered to it. Also, I see onDestroy() being hit in a nutshell, because Android manages activity life cycle, intents are not guaranteed to be delivered to it. I also tried extending a BaseActivity as mentioned in this stackoverflow question.
  • I also tried setting FLAG_ACTIVITY_CLEAR_TASK (in addition to usual FLAG_ACTIVITY_NEW_TASK), with no better results.

Now, I feel as if I am out of options. Has anyone faced similar problems? Is there something I can try? Is it possible to catch the exception and then rebind the service?

like image 545
Chaitanya Avatar asked Nov 06 '11 03:11

Chaitanya


1 Answers

In Activity B, implement an IBinder.DeathRecipient interface (possibly wrapped in a custom class) and register it with the IBinder from your service via IBinder.linkToDeath(). Your callback will be hit when/if the Service dies for some reason and Activity B can gracefully cleanup any internal book keeping it has as well as re-bind to the service.

like image 80
Larry Schiefer Avatar answered Oct 11 '22 23:10

Larry Schiefer