如何处理被杀死的服务上的DeadObjectException?

7
我在我的代码中遇到了DeadObjectException。下面我描述了我的设置以及我尝试解决该问题的方法。
一个Service S是从Application A启动的。 Activity B(来自另一个应用程序)使用MessengerIBinder接口与该服务通信。这个活动也是从同一个服务开始的。在这个活动中,当我按下按钮时,我应该向服务发送一条消息。我经常在按钮按下时得到DeadObjectException
我知道最可能的原因是 - 系统杀死并重新启动了服务,并且活动对其有旧引用。除此之外,在网上我没有找到太多信息。
我已经尝试过以下内容:
  • 我在服务中使用了startForeground(),我可以看到服务在持续运行(通知区域中的通知)。我仍然收到异常。
  • 在系统重启后,我一段时间内不会遇到此异常。
  • 异常是间歇性的。我没有100%的复制。但是,在以下情况下,我总是会遇到异常:
    1. 启动应用程序A(也启动服务S)。
    2. 启动活动B,一切正常。
    3. 通过重新部署应用程序A重新启动服务。
    4. 导航到活动B。异常发生了
    5. 此时,如果我重新启动活动B,则异常消失。
  • 这使我得出结论,如果我确保每次服务启动时活动B都是新的,则此异常将消失。然后,我尝试向活动B发送一个杀死意图,然后再启动它。(活动有一个BroadcastReceiver,并在onReceive()中调用finish())。问题是,如果活动暂停,Intent不会传递给它。此外,我看到onDestroy()被简要命中,因为Android管理活动生命周期,不能保证将意图传递给它。我还尝试扩展BaseActivity,如此stackoverflow问题中所述。
  • 我还尝试设置FLAG_ACTIVITY_CLEAR_TASK(除了通常的FLAG_ACTIVITY_NEW_TASK),但没有更好的结果。
现在,我觉得我没有其他选择了。有人遇到过类似的问题吗?有什么我可以尝试的吗?是否可能捕获异常,然后重新绑定服务?
1个回答

3

在Activity B中,实现一个IBinder.DeathRecipient接口(可能包装在自定义类中),并通过IBinder.linkToDeath()将其注册到您的服务的IBinder上。如果服务由于某些原因死亡,您的回调将被触发,Activity B可以优雅地清理任何内部簿记,并重新绑定到服务。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接