【问题标题】:LiveData vs Handler and LocalBroadcastLiveData vs Handler 和 LocalBroadcast
【发布时间】:2018-02-22 18:26:14
【问题描述】:

我有旧的 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 应该创建LiveData 并且想要结果的人应该observe 它, 当新数据到达时IntentService 应该调用postValue, 或者可能有一些珊瑚礁阻止LiveData在这里的使用?

【问题讨论】:

  • 是的,你可以这样做
  • 使用ResultReceiver进行Activity到IntentService的通信,可以在这些组件之间交换数据。它对于替代解决方案很有用。

标签: java android


【解决方案1】:

我认为LiveData 不会帮助您将任何数据从Service 发送到其他组件。

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

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

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

  1. 服务静态到达应用程序对象并设置一些数据。这是通过全局状态进行的通信,通常被认为是一种反模式。
  2. 通过 LocalBroadcastManager 进行通信

从上述两种机制中,我将只使用#2,不惜一切代价避免使用#1。

返回LiveData。

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

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

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

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

【讨论】:

【解决方案2】:

这两种方法都可以使用 LiveData,因为 LiveData 的目的是将它放在另一个线程上,并在发生变化时通知用户。似乎它肯定会取代LocalBroadcastManager.getInstance(this).sendBroadcast(in);,而您的 IntentService 将 postValue。只需让您的活动或任何需要了解变化的事物成为观察者即可。

【讨论】:

  • “只要让你的活动或任何需要注意变化的东西成为观察者”——这应该怎么做?
猜你喜欢
  • 2012-10-30
  • 1970-01-01
  • 2017-02-13
  • 1970-01-01
  • 2016-06-16
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
相关资源
最近更新 更多