【问题标题】:How to properly unbind services如何正确解绑服务
【发布时间】:2014-04-08 14:16:01
【问题描述】:

我有一个使用 BIND_AUTO_CREATE 绑定到我的 Activity 并以 START_STICKY 启动的服务。我没有明确调用 startService()。

由于当我的 Activity 被杀死时并不总是调用 onDestroy() 方法,并且 onStop() 方法不可行,因为我不希望我的服务在用户只需按下 Home 按钮时停止,我不知道何时解除绑定我的服务。

这是我的问题:

  1. 如果我希望我的 Service 在我的 Activity 处于活动状态时运行并在我的 Activity 被终止时停止,我应该在哪里取消绑定我的 Service?

  2. 当前调用 onDestroy() 方法并调用 unbindService() 时,不会触发 Service 的 onUnbind() 方法。为什么?

【问题讨论】:

  • 好问题。但是真的有必要绑定到服务吗?我真的很喜欢 IntentService 模式。那里的服务一旦完成它的任务就会关闭。通信是通过广播和 IntentReceivers 完成的。
  • 实际上,我有 2 个服务使用警报管理器每隔 x 秒唤醒一次以执行它们的任务。我想我可以使用我的活动上下文而不是使用服务!如果我理解得很好,只有在 Activity 被杀死时它们必须保持活动状态时才应该使用服务?
  • 如果你有AlarmManager,你可以通过实现一个对你的警报做出反应的广播接收器而无需服务。如果您希望在没有 UI 的情况下进行一些长时间运行的操作(即与服务器同步、更新数据库),您可能需要一项服务。

标签: android service bind ondestroy


【解决方案1】:

我没有明确调用 startService()

在这种情况下,覆盖onStartCommand(并返回START_STICKY)是没有意义的,因为它不会被调用。

1.如果我希望我的服务在我的 Activity 活着时运行,并在我的 Activity 被杀死时停止,我应该在哪里取消绑定我的服务?

如果你不想在onPause做,你可以在onDestroy解绑,没关系。在极少数情况下,当您的活动在没有onDestroy 的情况下被杀死时,它将被 Android 解除绑定(因此您的服务也将被解除绑定和正确销毁),如here 所述:

当您的客户端被销毁时,它将与服务解除绑定

至于

2.当onDestroy()方法当前被调用并且我调用 unbindService(),Service 的 onUnbind() 方法没有被触发。为什么?

我建议你绑定其他人,否则应该调用onUnbind。尝试在此方法中放置一个断点并验证它是否被命中。此外,请验证您的服务 onDestroy 在这种情况下是否被调用。

【讨论】:

  • 之所以调用我的 Service 的 onStartCommand,是因为我在 ServiceConnection 的 onServiceConnected() 方法中显式调用了它。我刚刚阅读了它的Javadoc,要求不要直接调用该方法......如果绑定的服务在其客户端被销毁时应该自动取消绑定,我想可以在 onDestroy 方法中取消绑定它。你是对的,我实际上有另一个服务绑定到我的第一个服务。我认为这样会更简单,但看起来它会使解除绑定过程复杂化。
  • 实际上,经过更多测试,我发现我的应用出现了一些奇怪的行为。当我将它从先前打开的应用程序列表中滑开时,我的 Activity 的 onDestroy 方法的 Log.d() 被调用,但里面的其余代码没有被调用。这就像 Android 想尽快杀死我的应用程序。我没有时间取消绑定我的服务(它们都绑定到我的 Activity 的上下文)。而且,与您所说的来源不同,我的服务没有解除绑定,因为我的 Activity 被破坏了......我确保没有调用 startService ,也没有调用 onStartCommand 。
  • “我的服务没有解除绑定,因为我的 Activity 被破坏了”-> 正如我参考的文档所解释的那样,它最终会从 android 杀死的活动中解除绑定。您提到您有两项服务,也许其中一项仍受其约束?最后,您能否确认您的服务“onDestroy”在所有内容都未绑定后被调用。我做了简单的测试,一切正常。
  • 我想我开始明白了,我的服务被销毁了(没有通过他们的 onUnbind 或 onDestroy 方法),只有他们的警报广播接收器还活着。但是由于我无法检测到我的服务的破坏,我无法从我的服务内部取消 AlarmManager 重复任务。我找到的解决方案是验证我的 Activity 的上下文是否还活着,如果不是,我会从内部取消警报广播接收器。我不认为这是阻止它的干净方法,我可能不应该为此目的使用服务。
猜你喜欢
  • 2012-02-26
  • 2015-11-25
  • 1970-01-01
  • 2017-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多