我有旧的Android/java代码,其中包含两个从IntentService
派生的代码,并且这些服务而不是在单独的进程中运行。
问题是如何从这些IntentService
返回结果。
使用Handler
+ Runnable
返回一个服务结果,在主循环中运行代码:
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
MyApplication.get().setFoo(someThing);
}
});
另一种是使用LocalBroadcastManager.getInstance(this).sendBroadcast(in);
向Activity
发送消息,Activity
在onResume
中通过BroadcastReceiver
订阅消息,在onPause
中通过取消订阅。
我说的对吗?在这两种情况下,都可以使用LiveData
来简化事情?
IntentService
应该创建LiveData
,谁应该observe
它,当新数据到达时,IntentService
应该调用postValue
,或者可能有一些珊瑚礁阻止了LiveData
的使用?
发布于 2017-09-21 05:32:12
我认为LiveData
不会帮助您从Service
向其他组件发送任何数据。
从任何Service
到其他组件的通信的问题是,您通常不会获得对Service
的直接引用,因此您不能直接“订阅”通知。
理论上,如果Service
运行在同一个进程中,可以绑定它,获取对Service
对象的引用,然后直接进行订阅。然而,这通常是一种过度的杀伤力,我认为这种模式并没有得到广泛的应用。
在您的示例中,有两种通信机制:
的anti-pattern.
从以上两种机制中,我会不惜一切代价只使用#2和避免#1。
回到LiveData
。
为了能够从Service
获取LiveData
对象,您需要拥有对该Service
的引用。这通常是不可能的,除非你在相同的进程中绑定Service
,或者使用一些涉及全局状态的丑陋的黑客攻击。
因此,LiveData
在此上下文中的用处非常有限。
顺便说一句,虽然LocalBroadcastManager还不错,但我发现这个机制太复杂了,而且受到了限制。因此,如果Service
在同一进程中运行,我更喜欢使用EventBus
以便从Service
与其他组件通信(反之亦然)。
你可以在我几天前写的SQLite benchmarking application中看到这样一个通信的例子。在此应用程序中,TestService
将状态更改和测试结果作为粘性事件发布到EventBus
,TestActivity
订阅这些事件。
发布于 2017-09-21 04:10:15
这两种方法都适用于使用LiveData,因为LiveData的目的是将它放在另一个线程上,并在发生更改时仍然通知用户。看起来它肯定会取代LocalBroadcastManager.getInstance(this).sendBroadcast(in);
,你的IntentService将会postValue。只要让你的活动或任何需要注意变化的东西成为观察者就行了。
https://stackoverflow.com/questions/46207758
复制相似问题