Android ViewModel 的职责是仅保存数据还是保存数据+视图控制器?

Abu*_*suf 5 android android-mvp android-viewmodel android-architecture-components

官方得知

ViewModel 类旨在以生命周期意识的方式存储和管理 UI 相关数据

但我认为很多开发人员ViewModel同时用作数据存储和控制器(例如调用存储库、数据的网络客户端)。我还使用 as 作为数据存储和视图控制器。

Android官方示例代码也有一些控制器逻辑。来自官方

class MyViewModel : ViewModel() {
  private val users: MutableLiveData<List<User>> by lazy {
     MutableLiveData().also {
        loadUsers()
     }
  }

  fun getUsers(): LiveData<List<User>> {
    return users
  }

  private fun loadUsers() {
    // Do an asynchronous operation to fetch users.
  }
}
Run Code Online (Sandbox Code Playgroud)

这里loadUsers可能会调用一些RepositoryNetworkClient。所以在这里它就像控制器一样。

我确信许多开发人员都这样做,但从定义上看ViewModel应该存储和管理 UI 相关数据,应该ViewModel充当控制器吗?

我发现了一些 stackoverflow 线程这个这个关于这个。

第一个接受的答案建议不要用作ViewModel控制器并使用控制器执行其他任务。

在第二个的评论部分@commonsware还建议不要使用数据以外的复杂东西。

所以我的问题是

  1. ViewModel建筑概念的实际责任是什么?
  2. 如果我必须做一些与View相关的方法调用[比如数据查询、网络调用和其他业务登录相关的东西]我应该在哪里做?
  3. 如果我必须使用控制器那么我如何连接View控制器以进行设备旋转并在片段之间共享控制器?

希望大家都清楚我的问题

提前致谢。

Epi*_*rce 3

这里loadUsers()可能会调用一些 Repository 或 NetworkClient 。所以在这里它就像控制器一样。

我确信许多开发人员都这样做,但是根据定义 ViewModel 应该存储和管理 UI 相关数据,ViewModel 应该充当 Controller 吗?

理论上,数据的检索应该是内部的LiveData,由拥有active observers并基于此决定要做什么(在onActive())中触发。如果 LiveData 实际上是 a MediatorLiveData,那么这也适用于与 绑定的任何块,因为仅当活动观察者观察 MediatorLiveData 时才会调用添加了a 的addSourceaddSourceMediatorLiveData

您可以NetworkBoundResource. ViewModel只存储数据,不知道数据加载。

从架构概念来看,ViewModel 的实际职责是什么?

如果您看到 Yigit Boyar(的创建者)的评论ViewModel

我是添加它的人(或团队的一部分),它与 MVVM 无关。这一切都是为了向人们提供一个应该将数据放置在何处的课程。

AAC 不是 MVVM 实现,VM 概念也不是仅作为 MVVM 的一部分存在。

事实上,这样做的主要动机是;我们一直告诉开发人员不要在 UI 控制器中管理数据,答案也是,那么在哪里呢?ViewModel 就是这个答案。

我们希望它成为视图层(片段、活动等)的模型。事后看来,选择一个新的名字可能会更好,但命名确实很难。

总之:ViewModel是MVC 场景中的模型C,其中是 Activity 或 Fragment,V是膨胀视图,MViewModel.

如果我必须做一些与View相关的方法调用[比如数据查询、网络调用和其他业务登录相关的东西]我应该在哪里做?

ViewModel 以 LiveData 的形式获取数据,并且通过从具有给定生命周期的 View 观察它来“激活”LiveData。

网络调用也应该以相同的方式触发(如果您遵循 LiveData 设计的方法)。

理论上,如果您有登录调用,您也可以在控制器而不是模型中执行此操作,因此您可以在片段中执行此操作,即使有像 Jetpack 数据绑定这样的技巧可以让您从视图调用方法直接从 XML 获取模型。

如果我必须使用控制器,那么我如何连接视图和控制器以进行设备旋转并在片段之间共享控制器?

ViewModel 会公开LiveData,并且如果您为此编写必要的代码,也可能会公开LiveEvent(不幸的是,Jetpack 团队没有提供,命令绑定也没有提供),并且视图或控制器可以在必要时直接调用其方法。ViewModel 跨配置更改存储(而不是跨进程死亡,ofc),因此它不应该保存直接视图引用。