LiveData与Handler和LocalBroadcast

时间:2017-09-13 22:30:51

标签: java android

我有旧的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 1}}。

我是对的,在这两种情况下都可以使用LiveData来简化事情吗?

IntentService应创建LiveData,哪些人希望结果为observe, 当新数据到达时IntentService应致电postValue, 或者可能有一些珊瑚礁阻止在这里使用LiveData

2 个答案:

答案 0 :(得分:4)

我认为LiveData无法帮助您将Service中的任何数据发送到其他组件。

从任何Service到其他组件的通信问题是您通常不会直接引用Service,因此您无法直接“订阅”通知。

理论上,如果Service在同一进程中运行,您可以绑定它,获取对Service对象的引用,然后直接执行订阅。然而,这通常是一种矫枉过正,我不认为这种模式被广泛使用。

在您的示例中,有两种通信机制:

  1. 服务静态到达Application对象并设置一些数据。这是一种通过全球状态的交流,通常被认为是一种反模式。
  2. 通过LocalBroadcastManager进行通信
  3. 从上述两种机制中,我只会使用#2并不惜一切代价避免#1。

    返回LiveData

    为了能够从LiveData获取Service个对象,您需要引用该Service。除非你在同一个进程中绑定Service,或者使用一些涉及全局状态的丑陋黑客,否则这通常是不可能的。

    因此,LiveData在这种情况下的用处非常有限。

    顺便说一下,虽然LocalBroadcastManager没问题,但我觉得这个机制过于复杂和限制。因此,如果Service在同一个流程中运行,我更倾向于使用EventBus来从Service与其他组件进行通信(反之亦然)。

    您可以在几天前写的SQLite benchmarking application中看到的这种通信示例。在此应用中,TestService将状态更改和测试结果发布为EventBus作为粘性事件,TestActivity订阅这些事件。

答案 1 :(得分:2)

这两种方法都可以使用LiveData,因为LiveData的目的是将它放在另一个线程上,并在某些内容发生变化时仍然通知用户。好像肯定会取代LocalBroadcastManager.getInstance(this).sendBroadcast(in);而你的IntentService会postValue。只需将您的活动或任何需要了解更改的内容变为观察者。