Android本地服务绑定和后台线程

Android本地服务绑定和后台线程,android,Android,我的应用程序有一个我想一直运行的本地服务,我通过让该服务启动另一个线程,并响应发送给其处理程序的请求来实现这一点。 绑定到服务将返回后台线程的处理程序,以便客户端活动可以发出请求 到目前为止还不错 我的应用程序使用需要使用该服务的Fragments来设置其初始状态。当片段被实例化以响应用户输入时,这是可以的,因为到那时服务已经绑定到片段的父活动。也就是说,ServiceConnection.onServiceConnected已被框架调用,并且活动知道其片段可用于与服务通信的处理程序 当我的活动

我的应用程序有一个我想一直运行的本地服务,我通过让该服务启动另一个线程,并响应发送给其
处理程序的请求来实现这一点。
绑定到服务将返回后台线程的处理程序,以便客户端活动可以发出请求

到目前为止还不错

我的应用程序使用需要使用该服务的
Fragment
s来设置其初始状态。当片段被实例化以响应用户输入时,这是可以的,因为到那时服务已经绑定到片段的父活动。也就是说,
ServiceConnection.onServiceConnected
已被框架调用,并且活动知道其片段可用于与服务通信的
处理程序

当我的活动被重新实例化以响应方向更改时,我的问题就开始了。从我对堆栈跟踪的阅读来看,在这种情况下,框架在调用
ServiceConnection.onServiceConnected
之前,在通过主线程消息循环的同一个过程中重新创建所有活动片段,因此它们无法在重新创建阶段访问服务

我找到的唯一解决方案是服务将与其后台线程关联的处理程序发布到应用程序全局状态。(我正在为此目的对应用程序进行子类化,尽管还有其他技术。)毕竟,我使用的是它的“线程性”而不是“服务性”


这似乎是一种简单而有效的方式来做一些Android似乎想让它变得尴尬和复杂的事情。除了通常对全局状态的一般性保留外,我的方法是否忽略了任何特定于Android的考虑因素?或者有什么更好的方法来实现同样的目标,我希望这是明确的?

如果我理解正确,您可能有兴趣研究一下。IntentService是一种服务,它在绑定时启动自己的线程,并在接收到意图时进行处理。你已经研究过了吗?

Android有自己的做事方式——这通常很尴尬,但是——公平地说——只是因为它是为了解决一些真正尴尬的问题

你可以:

  • 要么一直使用Android的架构
  • 或者尽量避免它(UI通常例外)
将这两种方法结合起来是很棘手的,因为它通常会让你面临两个世界中最糟糕的情况

在您的情况下(我知道您正在使用绑定服务,因为您需要传递真正的引用—因此,出于某种原因,切换到基于意图的服务是不可能的),我将同时删除服务和应用程序子类。在您描述的场景中,您根本不需要它们中的任何一个。一个简单的纯Java单例就可以了

另一个组合是采用Android方式。在这种情况下,您将围绕连接到
服务的代码创建一个包装器,并使其成为
加载程序的子类。这样,您就可以拥有一个由
LoaderManager
管理的连接实例


API的原始作者可能希望您重新编写应用程序,以便从内容提供商处读取所有数据,并由异步服务进行修改(也可能不是,谁知道…)。

谢谢。这使我走上了正轨。我不想使用
IntentService
,因为我的后台线程有我不想重新执行的特定初始化,但是
startService(Intent)
可能是我需要的。我没有对此给予足够的考虑。事实上,我认为这不会起作用,因为我需要通过引用后台线程的处理程序来传递任意对象,而且我认为我不能通过Intent机制来传递这些对象。我需要把它们放在我发送给处理程序的消息中。如果我错了,请纠正我,但是你不能让你试图传递的对象实现可包裹接口吗?。这将允许您整理/取消整理这些对象,并将它们传递给IntentService上新创建的线程。请查看此链接,了解如何执行此操作。谢谢,但我现在做的就是把我的东西打包。我需要的是推荐信。谢谢。据我记忆所及,我使用服务的最初原因是,我必须对广播接收器发出的警报做出响应,我不确定如果不是从服务启动线程,是否会有任何东西保护我的线程免于死亡。我误解了吗?线程与服务没有任何关联(这是怎么回事?!),所以不管它们是在服务内部还是其他地方创建的。如果您需要您的进程保持活动状态(有点像踏上了大门),那么您还可以创建一个完全空的类扩展服务并调用Context#startService。在您调用Context#stopService之前,它将被视为“正在运行”(无论这意味着什么…)。您不必以任何方式接触它,也不必将任何代码放入其中。我确实想到了线程如何与服务关联的问题,但如果不是这样的话,那么启动一个看起来是一个简单的方法,可以在资源耗尽的情况下击败Android管理应用程序组件的尝试。要管理我的后台线程的单个实例,最简单的方法似乎是将startService从alarm BroadcastReceiver中取消,并让该服务的onCreate启动线程。