我有旧的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
通过BroadcastReceiver
对onResume
消息进行订阅,并在onPause
取消订阅。
我是对的,在这两种情况下都可以使用LiveData
来简化事情吗?
IntentService
应该创buildLiveData
,谁想要结果应该observe
它,当新的数据到达IntentService
应该调用postValue
,或者可能有一些珊瑚礁来防止在这里使用LiveData
?
我认为, LiveData
不会帮助您将任何数据从Service
发送到其他组件。
从任何Service
到其他组件的通信问题是,您通常不会直接获得Service
引用,因此您不能直接“订阅”通知。
理论上,如果Service
运行在同一个进程中,你可以绑定它,获得对Service
对象的引用,然后直接执行订阅。 但是,这往往是一个矫枉过正,我没有看到这种模式被广泛使用。
在你的例子中,有两种沟通机制:
从以上两种机制中,我只用#2,不惜一切代价避免#1。
回到LiveData
。
为了能够从Service
获得LiveData
对象,您将需要引用该Service
。 这通常是不可能的,除非你在相同的过程中绑定Service
,或使用涉及全局状态的一些丑陋的黑客。
因此,在这种情况下LiveData
有用性是非常有限的。
顺便说一句,虽然LocalBroadcastManager是好的,我觉得这个机制太复杂和限制。 因此,如果Service
运行在同一个进程中,我更愿意使用EventBus
来从Service
与其他组件进行通信(反之亦然)。
你可以在几天前写的SQLite基准testing应用程序中看到这样一个通信的例子。 在这个应用程序中, TestService
状态更改和testing结果作为粘滞事件发布到EventBus
, TestActivity
订阅这些事件。
这两种方法都适用于使用LiveData,因为LiveData的目的是让它在另一个线程上,并且在某些事情发生变化时仍然通知用户。 看起来像它肯定会取代LocalBroadcastManager.getInstance(this).sendBroadcast(in);
而你的IntentService会postValue。 只要有你的活动或任何需要意识到变化成为观察员。