【问题标题】:Android Architecture Components ViewModel - communication with Service/IntentServiceAndroid 架构组件 ViewModel - 与 Service/IntentService 的通信
【发布时间】:2017-10-11 07:35:51
【问题描述】:

我正在探索 Google 的 Android Architecture Components。在我的项目中,我依赖ServicesIntentServices。从 IntentService 或 Service 与应用程序的 ViewModel 通信的正确方法是什么?使用 LiveData 可以实现吗?

【问题讨论】:

  • MVVM 架构中的什么角色会扮演你的服务角色?
  • IntentService 用于远程数据获取,gps 位置用于服务。
  • 我认为,在这种情况下,您应该将您的服务视为 MVVM 架构中的模型,并且 ViewModel 应该与服务交互(反之亦然)以检索数据并将其提供给 View(Activity 或片段)使用像 LiveData 这样的架构机制。服务可能对 ViewModel 一无所知。
  • @Nikolay viewmodel 如何引用服务?如果我错了,请纠正我,但这不是反模式,因为服务是 Android 框架的一部分。 Viewmodel 永远不应该直接与它们通信。这就是为什么有 LiveData。 Plus Services 和 ViewModel 的生命周期不同。它最终可能会泄漏其中一个吗?我错了吗?
  • @Archie,是的,你是对的。 ViewModel 不应直接与 Service 或其他 Adnroid 组件交互。当我写这篇文章时,我并没有完全理解 SOLID 原则。在 Lyla 的帖子中,完美的 MVVM 架构图。

标签: android mvvm android-architecture-components android-viewmodel


【解决方案1】:

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


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

您的远程数据源代码将有一个 observable(Rx Flowable、LiveData 等),我将其称为 observable A,用于您的 Intent 服务下载的数据。您的 Repository 类(如果您使用一个)将有一个可观察的 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. 当您的存储库完成后,它会使用新处理的数据设置 observable B。
  4. 这会触发您的 ViewModel,因为它已订阅 - 它执行 ViewModel 所执行的数据处理类型,即格式化数据以便为视图做好准备,然后设置 observable C...
  5. 这会触发更新 UI 的 Activity/Fragment/View

这基本上是一长串的观察者关系。在每个级别,都会进行适当的处​​理,然后设置一个可观察对象,该对象会使用新数据触发下一个级别。这样可以避免与 IntentService/Repository/ViewModel 的强耦合。

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

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

LiveData 是lifecycle-aware,这使得它特别适合通过具有生命周期(活动/片段)的事物进行观察。 observe 方法采用 LifecycleOwner

对于存储库/网络代码中的 B 和 A 等观察者,可能不会有 LifecycleOwner。这意味着要么使用observerForever,要么使用另一个可观察对象,如 RxFlowable。

【讨论】:

  • ViewModel guide 声明:ViewModel 对象可以包含 LifecycleObserver,例如 LiveData 对象。然而,ViewModel 对象绝不能观察生命周期感知可观察对象的变化,例如 LiveData 对象。
  • 这太棒了!谢谢!
  • 你应该如何首先获得系统服务对存储库的引用?
  • 什么是远程数据源?是服务本身吗?它是一个启动并绑定到服务并在服务生命周期内保持不变的单例吗?如果是后者,它是否应该继承一些类,或者它只是一个 POJO?
  • @CheesusCrust 正是我的问题!!我不认为这个答案是正确的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-12
  • 1970-01-01
  • 1970-01-01
  • 2018-05-12
  • 2021-01-06
  • 2017-11-17
相关资源
最近更新 更多