2

我的应用程序有一个我想一直运行的本地服务,我通过让服务启动另一个线程并响应发送到它的请求来完成Handler. 绑定到服务返回后台线程的处理程序,以便客户端活动可以发出请求。

到目前为止,一切都很好。

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

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

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

这似乎是一种简单而有效的方法来做一些 Android 似乎想要变得尴尬和复杂的事情。除了通常对全局状态的一般保留之外,我的方法是否忽略了任何特定于 Android 的注意事项?或者有什么更好的方法来实现相同的目标,我希望这是清楚的?

4

2 回答 2

1

如果我理解正确,您可能有兴趣研究IntentService。IntentService 是一个服务,它在绑定时启动自己的线程,并在收到 Intent 时对其进行处理。你已经调查过了?

于 2013-07-01T13:45:58.663 回答
1

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

你可以:

  • 要么一直使用Android的架构,
  • 或尽量避免它(通常 UI 除外)。

将这两种方法结合起来是很棘手的,因为它通常会让你陷入两全其美的境地。

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

另一种组合是采用 Android 方式。在这种情况下,您将围绕连接到的代码创建一个包装器,Service并使其成为 a 的子类Loader。这样,您可以拥有一个由LoaderManager.

可能 API 的原始作者希望您重新设计您的应用程序,以便从内容提供者读取所有数据并由异步服务修改(或者可能不会,谁知道......)。

于 2013-07-01T14:07:51.380 回答