Android 架构组件 ViewModel - 与 Service/IntentService 的通信

Android Architecture Components ViewModel - communication with Service/IntentService

我正在从 IntentService 或服务探索 Google 的 Android Architecture Components. In my project I'm relying on Services and IntentServices. What is the correct way to communicate with app's ViewModel?使用 LiveData 可以实现吗?

TL;DR 这是可以实现的 - 使用观察者关系。您的 IntentService 和可能的位置服务应该不会 知道您的 ViewModel。考虑使用存储库。可以使用 LiveData(参见 postValue)。它有利于更新 UI(ViewModel 到 Activity 通信),因为它具有生命周期感知能力。当你不更新 UI 时,你可以考虑 RxJava。


这取决于您所遵循的架构。如果您正在做类似于 Guide to App Architecture 中描述的事情,您的 IntentService 可能是由您的远程数据源代码启动的:

您的远程数据源代码将有一个可观察对象(Rx Flowable、LiveData 等),我将其称为可观察对象 A,用于您的意图服务下载的数据。您的 Repository class(如果您使用一个)将有一个可观察的 b,而您的 ViewModel 将有一个可观察的 c。

Repository 订阅你网络代码中的 observable(observable A),ViewModel 订阅你 Repository 中的 observable(observable B),你的 Activity/Fragment/View 订阅你 ViewModel 中的 observable(observable C)。那么...

  1. IntentService 取回数据并设置 observable A
  2. 这会触发您的存储库,因为它已订阅 - 它执行存储库应该执行的数据处理类型,例如将数据保存到数据库中。
  3. 存储库完成后,它会使用新处理的数据设置可观察 B。
  4. 这会触发您的 ViewModel,因为它已订阅 - 它执行 ViewModel 执行的数据处理类型,即格式化数据以便为视图做好准备,然后设置可观察的 C...
  5. 这会触发您的 Activity/Fragment/View 更新 UI

它基本上是一长串一直向上的观察者关系。在每个级别,完成适当的处理,然后设置一个可观察对象,用新数据触发下一个级别。这使您可以避免与 IntentService/Repository/ViewModel.

的强耦合

您的服务不会知道您的 ViewModel(或存储库,如果有的话),它们应该简单地设置一个可观察对象的值。如果你想跳过存储库,你可以让 ViewModel 观察你的远程数据源 class,但如果你需要执行任何逻辑,比如将下载的数据保存到数据库,你可能需要一个存储库。

关于 LiveData 的两个注意事项 - 如果您在进行后台操作时需要更新 LiveData,请使用 postValue

LiveData 是 lifecycle-aware, which makes it particularly well suited for observation by things with lifecycles (Activities/Fragments). The observe 方法采用 LifecycleOwner.

对于 Repository/Networking 代码中的 B 和 A 这样的观察者,可能不会有 LifecycleOwner。这意味着要么做一些事情,比如使用 observerForever,要么使用另一个 observable,比如 RxFlowable。