【问题标题】:Is it a good idea to bind on an Android service in the application class?在应用程序类中绑定 Android 服务是个好主意吗?
【发布时间】:2017-08-11 13:55:13
【问题描述】:

我有一个包含会话映射(键、会话)的 Android 前台服务。在我的活动中,我收到一个密钥,我想从服务中获取会话。所以我将我的每个活动绑定到服务,我可以要求服务使用我的密钥获取我的会话。但是这样做意味着我必须等待onServiceConnected() 才能获得会话。

在我的应用程序类中绑定一次服务并将我的服务放在一个静态变量中是不是一个好主意,然后我所有的活动都可以直接在他们的onCreate()中访问服务而不是等待onServiceConnected()的调用?但是确定我的静态变量会一直存在吗?如果需要资源,您知道 Android 是否可以删除该静态变量?我猜应用程序实例永远不会被删除,对吗?因此,将我的服务保存在静态变量中可能是个好主意。你怎么看?

【问题讨论】:

    标签: android variables static android-service foreground


    【解决方案1】:

    您正在尝试做的事情听起来像是 React 中某种调度程序的肮脏实现,我很想自己做,但由于时间不够而没有做。请让我们知道您的结果。

    我建议使用 Messager,文档有关于它的信息,所以不需要静态 https://developer.android.com/guide/components/bound-services.html?hl=en-419

    是的,Android 操作系统可以清除任何东西,它可以杀死服务,它可以使变量为空。大多数情况下这不会发生,因为它只会优先处理前台应用程序。因此,如果用户打开 10 个应用程序并且您在后台,它可能会。这对我来说似乎没问题。有时我也遇到过变量在片段中变为空的情况,但后来我缩小了变量范围并修复了它。

    此外,如果您正在考虑这一点,请尝试使用 EventBus 库或使用 ReactJava,也许 Realm ORM 甚至 Firebase 可以帮助您。

    【讨论】:

    • 我的应用程序允许您在远程桌面上打开会话并共享桌面。这些会话,我不能接受 Android 删除它们。这就是为什么我的服务在前台运行的原因,因为我必须保持会话处于活动状态。所以我所有的开放会话都保留在服务中。但是,当我打开一个活动以显示特定会话的屏幕时,我必须获取该会话。为此,我将我的活动绑定在服务上,然后询问会话。但是当我打开活动而不是等待服务获取我的会话时,我希望立即进行会话。这就是为什么我想让它保持静态
    • 我坚持必须使用信使来完成通信developer.android.com/guide/components/… 然后你必须使用持久性,为此我建议使用 SharedPreference,简单的键值数据你只需要上下文,因为服务可以将其用作上下文 developer.android.com/training/basics/data-storage/… 在服务中将会话存储在 SharedPreference 中,Activity 向 Messenger 询问从 SharedPrefference 获取它
    • Android 可以杀死托管应用程序的操作系统进程,但随后所有应用程序组件都将被杀死。一旦Application 对象被实例化,它就永远不会被删除(垃圾收集)。它充当单例,Android 摆脱它的唯一方法是杀死托管应用程序的操作系统进程。
    【解决方案2】:

    您可以在 Application 类中绑定到 ServiceApplication 实例基本上是一个单例,只要托管您的应用程序的操作系统进程还存在,它就会存在。在某些时候,Android 会杀死托管您应用程序的操作系统进程,然后您的所有应用程序组件都会消失(Application 实例、ServiceActivity 实例等)。如果用户返回到您的应用,Android 将创建一个新的操作系统进程,实例化一个新的Application 实例,然后根据需要实例化您的应用组件。

    【讨论】:

      【解决方案3】:

      应用程序本身并不像其他Android组件那样有生命周期,所以如果你在它的onCreate()回调中调用bindService(),则不能保证调用unbindService(),这可能会导致内存泄漏和不可预知的状态.其他人也指出here

      相反,您可以start your service in the foreground(显示类似“远程桌面管理器正在运行”的通知),这应该使您的应用程序保持活动状态,并使map<key, session> 成为您应用程序中的静态变量.通过这种方式,Activities 可以在没有连接延迟的情况下检索会话。只是不要忘记在所有会话关闭时调用stopService(Intent intent)stopSelf() 来停止服务。

      顺便说一句,即使考虑到 Android O 的背景限制,它也应该可以工作。

      【讨论】:

      • 什么意思,没有生命周期? onCreate 和 onTerminate 呢
      • onTerminate 实际上从未被调用过,你不能依赖它。
      • 你不能既依赖onDestroy,但仍然是Activity生命周期的一部分。然而,我明白你的观点,我不赞成它的实用主义。那么问题来了,如果我们不关心取消绑定服务怎么办?我们可以交替使用任何 Activity 中的任何 onStop 向服务发送消息,然后执行我们需要的操作
      • 我同意你的观点,我们也可以在最后一个关闭活动上调用 onStop,但我认为无论如何我们都需要这样做。关于不关心我们是否取消绑定服务,我理解它的思维方式,特别是如果我们在最后一分钟修复崩溃或其他东西。但似乎他正在从头开始设计解决方案,并设计一些已经接受其缺陷作为绝对真理的东西,这似乎不是开始某事的好方法。
      • 是的!这就是为什么我还建议查看其他解决方案,例如 EventBus、ReactJava、Realm 或 Firebase。
      猜你喜欢
      • 2011-05-14
      • 1970-01-01
      • 2019-10-19
      • 1970-01-01
      • 2016-02-24
      • 2014-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多