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

6

你的服务在MVVM架构中将扮演什么角色? - Nikolay
1
IntentService 用于远程数据获取,GPS 位置用于 Service。 - Jan Slominski
2
我认为,在这种情况下,你应该将你的服务视为MVVM架构中的模型,而ViewModel应该与服务进行交互(但不是反过来),以检索数据并使用类似LiveData的架构机制将其提供给View(Activity或Fragment)。服务可能对ViewModel一无所知。 - Nikolay
3
@Nikolay,ViewModel如何引用Service?请纠正我如果我错了,因为Service是Android框架的一部分,所以这不是一个反模式吗?ViewModel不应直接与它们通信。这就是为什么有LiveData的原因。另外,Service和ViewModel的生命周期不同。可能会造成其中一个泄漏,对吗?我错了吗? - Archie G. Quiñones
1
@Archie,是的,你说得对。ViewModel不应直接与Service或其他Android组件交互。当我写这个时,我没有完全理解SOLID原则。在Lyla的帖子中有一个完美的MVVM架构图。 - Nikolay
1个回答

25
TL;DR 可以实现 - 使用观察者模式。您的 IntentService 和可能的位置服务不应该知道您的 ViewModel。考虑使用 Repository。可以使用 LiveData(请参见postValue)。它很适合更新 UI(ViewModel 到 Activity 的通信),因为它具有生命周期感知功能。当您不更新 UI 时,可以考虑使用 RxJava。

这取决于你遵循的架构。如果你正在执行类似于应用程序架构指南中描述的操作,则你的IntentService可能是由远程数据源代码启动的:

enter image description here

你的远程数据源代码应该有一个可观察对象(Rx Flowable,LiveData等),我将其称为可观察对象A,用于由你的意图服务下载的数据。如果你使用Repository类,则它应该有一个可观察对象B,而你的ViewModel则应该有一个可观察对象C。
Repository订阅你的网络代码中的可观察对象(可观察对象A),ViewModel订阅你的Repository中的可观察对象(可观察对象B),Activity/Fragment/View订阅你的ViewModel中的可观察对象(可观察对象C)。然后...
1. IntentService获取数据并设置可观察对象A 2. 这会触发你的Repository,因为它已经订阅了-它执行存储数据到数据库之类的Repository应该做的数据处理类型。 3. 当Repository完成时,它使用新处理的数据设置可观察对象B。 4. 这会触发你的ViewModel,因为它已经订阅了-它执行ViewModels所做的数据处理类型,即格式化数据以便于视图使用,然后设置可观察对象C... 5. 这会触发你的Activity/Fragment/View,从而更新UI。
这基本上是整个观察者关系链。在每个级别上,适当的处理都会完成,然后它会设置一个可观察对象,从而触发具有新数据的下一个级别。这使你可以避免与IntentService/Repository/ViewModel之间的强耦合。
你的Services不应该意识到你的ViewModel(或者如果你有的话,Repository),它们只需设置可观察对象的值即可。如果你想跳过使用Repository,你可以让ViewModel观察你的远程数据源类,但是如果你需要执行任何逻辑,比如将下载的数据保存到数据库中,则可能需要一个Repository。

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

LiveDatalifecycle-aware 的,这使它特别适合由具有生命周期的内容(活动/片段)观察。observe 方法需要一个 LifecycleOwner

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


1
ViewModel指南 指出:ViewModel对象可以包含LifecycleObservers,例如LiveData对象。但是ViewModel对象绝不能观察生命周期感知型的可观察对象,例如LiveData对象。 - Exerion
1
你应该如何首先获取到仓库的系统服务引用呢? - CheesusCrust
1
@CheesusCrust,完全就是我的问题!!我不认为这个答案是正确的。 - Archie G. Quiñones
RxJava 的学习曲线很陡峭,可能需要六个月的时间才能掌握。对于 OP 的问题来说不值得。 - IgorGanapolsky
这只是增加了另一个不必要的层,因为viewModel只是将数据传递到activity... - laim2003
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接