【问题标题】:Android: How bound Service can be noticed about killed client?Android:关于被杀死的客户端,如何注意到绑定服务?
【发布时间】:2012-01-29 21:17:25
【问题描述】:

我绑定了一个 Activity 和 Service。

如果 Service 被系统杀死,Activity 会被注意到,因为 ServiceConnection.onServiceDisconnected(ComponentName) 会被调用。

但是当Activity的进程被系统杀掉后,有没有对Service的回调呢?服务如何知道客户端已被杀死? (当整个进程被杀死时,没有onDestroy()方法调用,可惜)

我现在看到的唯一方法是:

我的Service 中有回调列表:

RemoteCallbackList<IModConnClient> mCallbacks

当我通过调用mCallbacks.beginBroadcast(); 开始广播时,它返回给我一些客户。所以,我可以记住以前的客户数量并检查它是否减少了。但这似乎不是一个很好的解决方案。我想要一些回调,但不幸的是我找不到。

谁能给个建议?

【问题讨论】:

  • 为什么你的活动和你的服务不在同一个进程中?
  • @CommonsWare,那是因为我需要创建将使用AIDL 与其他应用程序通信的服务。我的出发点是这个开发指南:goo.gl/pJBqX。我在 AndroidManifest.xml 中有 android:process=":remote" 用于此服务。

标签: android service android-activity kill


【解决方案1】:

我找到了解决办法。

RemoteCallbackList documentation 中所述,“如果注册的回调进程消失,该类将自动将其从列表中删除。如果您想在这种情况下做额外的工作,您可以创建一个实现 onCallbackDied(E) 方法的子类。"

所以,我为RemoteCallbackList 和接口IRemoteCallbackDied 创建了一个子类:

   private interface IRemoteCallbackDied<E extends IInterface> {
      public void remoteCallbackDied(E callback, Object cookie);
   }

   private final class RemoteCallbackListWithDiedCB<E extends IInterface> extends RemoteCallbackList<E> {
      IRemoteCallbackDied<E> mRemoteCallbackDied;

      public RemoteCallbackListWithDiedCB(IRemoteCallbackDied<E> mRemoteCallbackDied)
      {
         this.mRemoteCallbackDied = mRemoteCallbackDied;
      }

      @Override public void onCallbackDied(E callback, Object cookie){
         super.onCallbackDied(callback, cookie);
         this.mRemoteCallbackDied.remoteCallbackDied(callback, cookie);
      }
   }

然后,我为IRemoteCallabackDied 创建了实现:

   private final IRemoteCallbackDied<IModConnClient> mRemoteCallbackDied = new IRemoteCallbackDied<IModConnClient>() {
      public void remoteCallbackDied(IModConnClient mModConnClient, Object cookie)
      {
         Log.v("my_tag", "remote callback died!");
         /*
          * Some code
          */
      }
   };

最后,我的回调列表是这样定义的:

private RemoteCallbackListWithDiedCB<IModConnClient> mClients = new RemoteCallbackListWithDiedCB<IModConnClient>(mRemoteCallbackDied);

【讨论】:

    【解决方案2】:

    也有一个简单的解决方案。它是onTaskRemoved 服务方法。它会在活动被终止时通知您。在文档上。它说…………

    public void onTaskRemoved (Intent rootIntent)

    在 API 级别 14 中添加 如果服务当前正在运行并且用户已删除来自服务应用程序的任务,则会调用此方法。如果您设置了 ServiceInfo.FLAG_STOP_WITH_TASK 那么您将不会收到此回调;相反,服务将被停止。

    参数 rootIntent 用于启动要删除的任务的原始根 Intent。

    如果你想知道整个进程何时在没有 onDestroy 的情况下被杀死,你需要知道DeathRecipient。有一个kind blog post

    我希望这个答案能以另一种方式帮助你:)

    【讨论】:

    • 谢谢,但 onTaskRemoved 方法仅在 API 级别 14 中添加,但目前我们使用 API 级别 7 定位设备。不过感谢您提供的信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多