我正在探索 Google 的 Android Architecture Components .在我的项目中,我依赖 Services和 IntentServices .与应用程序的 ViewModel 通信的正确方式是什么?来自 IntentService 或服务?使用 LiveData 可以实现吗?
最佳答案
TL;DR 这是可以实现的——使用观察者关系。您的 IntentService 和可能的位置服务应该不知道您的 ViewModel。考虑使用存储库。可以使用 LiveData(参见 postValue
)。它有利于更新 UI(ViewModel 到 Activity 的通信),因为它具有生命周期感知能力。当您不更新 UI 时,您可以考虑使用 RxJava。
这取决于您所遵循的架构。如果您正在做类似于 Guide to App Architecture 中描述的事情,你的 IntentService 可能是由你的远程数据源代码启动的:
您的远程数据源代码将有一个可观察对象(Rx Flowable、LiveData 等),我将其称为可观察对象 A,用于您的 Intent 服务下载的数据。您的 Repository 类(如果您使用一个)将有一个可观察的 b,而您的 ViewModel 将有一个可观察的 c。
Repository 订阅您网络代码中的可观察对象(observable A),ViewModel 订阅您 Repository 中的可观察对象(observable B),您的 Activity/Fragment/View 订阅您 ViewModel 中的可观察对象(observable c) .然后……
- IntentService 取回数据并设置 observable A
- 这会触发您的存储库,因为它已订阅 - 它执行存储库应该执行的数据处理类型,例如将数据保存到数据库中。
- 当您的存储库完成后,它会使用新处理的数据设置可观察 B。
- 这会触发您的 ViewModel,因为它已订阅 - 它执行 ViewModel 执行的数据处理类型,即格式化数据以便为 View 做好准备,然后设置可观察的 C...
- 这会触发更新 UI 的 Activity/Fragment/View
它基本上是一长串一直向上的观察者关系。在每个级别,完成适当的处理,然后设置一个可观察对象,用新数据触发下一个级别。这使您可以避免与 IntentService/Repository/ViewModel 的强耦合。
您的服务不会知道您的 ViewModel(或存储库,如果有的话),它们应该简单地设置一个可观察对象的值。如果您想跳过存储库,您可以让 ViewModel 观察您的远程数据源类,但如果您需要执行任何逻辑,例如将下载的数据保存到数据库,您可能需要一个存储库。
关于 LiveData
的两个注意事项 - 如果您需要在执行后台操作时更新 LiveData,请使用 postValue
.
LiveData 是 lifecycle-aware ,这使得它特别适合观察具有生命周期的事物(Activities/Fragments)。 observe
方法采用 LifecycleOwner
。
对于存储库/网络代码中的 B 和 A 等观察者,可能不会有 LifecycleOwner。这意味着要么做一些事情,比如使用 observerForever
,或使用另一个可观察对象,例如 RxFlowable。
关于Android 架构组件 ViewModel - 与 Service/IntentService 的通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46682425/