android 架构组件 - viewmodel

ViewModel类旨在以生命周期的方式存储和管理与ui相关的数据。
ViewModel类允许数据在诸如屏幕旋转之类的配置更改中存活。

注意:要将ViewModel导入到您的Android项目中,请参见向您的项目添加组件。

Android框架管理UI控制器的生命周期,比如activities和fragments。
该框架可能会决定销毁或重新创建UI控制器,以响应完全超出您控制的某些用户操作或设备事件。

如果系统破坏或重新创建一个UI控制器,那么存储在其中的任何与UI相关的数据都将丢失。
例如,你的应用可能会在其中一个activity中包含一个用户列表。
当为配置更改重新创建activity时,新activity必须重新获取用户列表。
对于简单的数据,该activity可以使用onSaveInstanceState())方法,并从onCreate())中的bundle中恢复其数据,但是这种方法只适用于少量的数据,这些数据可以序列化然后反序列化,而不是像用户列表或位图那样的潜在的大量数据。

另一个问题是UI控制器经常需要进行异步调用,这可能需要一些时间才能返回。
UI控制器需要管理这些调用,并确保系统在被销毁后清除它们,以避免潜在的内存泄漏。
这种管理需要大量的维护,并且在为配置更改重新创建对象的情况下,由于对象可能不得不重新发出已经发出的调用,这是对资源的浪费。

诸如activities和fragments之类的UI控制器主要是用来显示UI数据、对用户操作作出反应,或者处理操作系统通信,比如权限请求。
要求UI控制器也负责从数据库或网络加载数据,这增加了类的膨胀。
给UI控制器分配过多的责任会导致一个单独的类,它试图独自处理应用程序的所有工作,而不是将工作委托给其他类。
以这种方式为UI控制器分配过多的责任也会使测试变得更加困难。

将视图数据所有权与UI控制器逻辑分离是更容易、更高效的。

实现ViewModel

架构组件为UI控制器提供ViewModel助手类,负责为UI准备数据。
在配置更改期间,ViewModel对象将自动保留,以便它们保存的数据立即可用到下一个activity或fragment实例。
例如,如果您需要在应用程序中显示一个用户列表,请确保将责任分配给一个ViewModel,而不是一个activity或fragment,如下面的示例代码所示:

1234567891011121314
public class  extends ViewModel {    private MutableLiveData<List<User>> users;    public LiveData<List<User>> getUsers() {        if (users == null) {            users = new MutableLiveData<List<Users>>();            loadUsers();        }        return users;    }

    private void loadUsers() {

    }}

然后,您可以从以下activity中访问该列表:

1234567891011
public class MyActivity extends AppCompatActivity {    public void onCreate(Bundle savedInstanceState) {        // Create a ViewModel the first time the system calls an activity's onCreate() method.        // Re-created activities receive the same MyViewModel instance created by the first activity.

        MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);        model.getUsers().observe(this, users -> {            // update UI        });    }}

如果该activity被重新创建,它将收到第一个activity创建的MyViewModel实例。
当所有者activity完成后,框架调用ViewModel对象的onCleared())方法,以便它可以清理资源。

??:ViewModel永远不能引用视图、Lifecycle或任何可能引用activity上下文的类。

ViewModel对象的设计是为了比具体的视图实例或LifecycleOwners实例活得更活。
这个设计还意味着您可以更容易地编写测试来覆盖ViewModel,因为它不知道视图和生命周期对象。
ViewModel对象可以包含LifecycleObservers,比如LiveData对象。
然而,ViewModel对象永远不能观察对生命周期敏感的观察对象的变化,例如LiveData对象。
如果ViewModel需要Application context,例如找到一个系统服务,它可以扩展AndroidViewModel类,并拥有一个在构造函数中接收到Application的构造函数,因为Application类扩展了Context。

ViewModel的生命周期

ViewModel对象是在获得ViewModel时被传递到ViewModelProvider的生命周期的范围。
ViewModel仍然存在于内存中,直到它被限定的生命周期永久地消失:在activity的情况下,当它finishes时,在一个fragment中,当它被detached时。

图1演示了一个activity的各个 大专栏  android 架构组件 - viewmodel生命周期状态,当它进行轮转,然后结束。
插图还显示了与相关活动生命周期相邻的ViewModel的生命周期。
这个特殊的图说明了activity的状态。
同样的基本状态也适用于fragment的生命周期。

在系统调用activity对象的onCreate()方法时,通常需要一个ViewModel。
系统可以在activity的整个生命周期中多次调用onCreate(),例如在设备屏幕被旋转时。
ViewModel存在于您第一次请求ViewModel时,直到activity完成并销毁

fragments之间共享数据

在一个activity中,两个或多个fragments需要相互通信是很常见的。
设想一个常见的master-detail fragments,其中有一个fragment,用户从一个列表中选择一个项目,另一个fragment显示所选项的内容。
这个案例并不简单,因为两个fragments都需要定义一些接口描述,而所有者activity必须将两者结合在一起。
此外,两个fragments必须处理另一个fragment尚未创建或可见的场景。

这个常见的痛点可以通过使用ViewModel对象来解决。
这些fragments可以使用它们的activity范围来共享一个视图模型,以处理这种通信,如下面的示例代码所示:

1234567891011121314151617181920212223242526272829303132
public class SharedViewModel extends ViewModel {    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) {        selected.setValue(item);    }

    public LiveData<Item> getSelected() {        return selected;    }}

public class MasterFragment extends Fragment {    private SharedViewModel model;    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);        itemSelector.setOnClickListener(item -> {            model.select(item);        });    }}

public class DetailFragment extends Fragment {    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);        model.getSelected().observe(this, { item ->           // Update the UI.        });    }}

请注意,在获取ViewModelProvider时,两个fragments都使用getActivity()。
因此,这两个fragments都接收相同的SharedViewModel实例,该实例的作用域是activity。

这种方法提供了以下好处:

  • activity不需要做任何事情,也不需要知道任何关于这种通信的信息。
  • 除了SharedViewModel合同之外,Fragments不需要相互了解。
    如果其中一个fragments消失了,另一个则继续正常工作。
  • 每个fragment都有自己的生命周期,并且不受另一个生命周期的影响。
    如果一个fragment替换另一个fragment,UI将继续工作,没有任何问题。

用ViewModel替换Loaders

CursorLoader这样的Loader类经常用于同步数据库数据保持应用程序的UI。
您可以使用ViewModel,以及其他一些类来替换loader。
使用ViewModel将UI控制器与数据加载操作分离,这意味着类之间的强引用较少。

在使用loaders的一种常见方法中,应用程序可能使用一个CursorLoader来观察数据库的内容。
当数据库中的值发生变化时,loader会自动触发数据的重新加载,并更新UI:

ViewModel使用Room和LiveData来替换loader。
ViewModel确保数据在设备配置更改中得以保存。
当数据库发生变化时,Room会通知您的LiveData,而LiveData则会用修改后的数据更新您的UI。

这篇博客文章描述了如何使用一个带有LiveData的ViewModel来替换一个AsyncTaskLoader

随着您的数据变得越来越复杂,您可能会选择一个单独的类来加载数据。
ViewModel的目的是封装UI控制器的数据,使数据能够在配置更改中存活。
有关如何在配置更改中加载、持久化和管理数据的信息,请参见保存UI状态

Android应用程序架构的指南建议构建一个存储库类来处理这些函数。

原文地址:https://www.cnblogs.com/liuzhongrong/p/12288948.html

时间: 2024-08-29 21:38:21

android 架构组件 - viewmodel的相关文章

Android 架构组件 之 ViewModel 学习

Overview 今天在学习的过程中,我学了一下Android的架构组件之ViewModel的学习操作.ViewModel也是属于我们的Android Jetpack的一部风. Android 开发者文档中是这么说的: ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据.ViewModel 类让数据可以在发生旋转等配置更改后继续存在的. 看一看我们是如何使用ViewModel的 架构组件为界面控制器提供了ViewModel 辅助程序类,该类负责为界面准备数据,在配置更改期间会

Android Jetpack组件 - ViewModel,LiveData使用以及原理

本文涉及的源码版本如下: com.android.support:appcompat-v7:27.1.1 android.arch.lifecycle:extensions:1.1.1 android.arch.lifecycle:viewmodel:1.1.1 android.arch.lifecycle:livedata:1.1.1 什么是ViewModel, 以及工作原理 ViewModel用于存储和管理UI相关的数据,ViewModel有自己生命周期,会根据fragment,activi

Android官方架构组件:Lifecycle详解&amp;迪士尼彩乐园平台搭建原理分析

在过去的谷歌IO大会上,Google官方向我们推出了 Android Architecture Components,其中谈到Android组件处理生命周期的问题,向我们介绍了 Handling Lifecycles. 同时,如何利用 android.arch.lifecycle 包提供的类来控制数据.监听器等的 lifecycle.同时,LiveData 与 ViewModel 的 lifecycle 也依赖于 Lifecycle 框架. 经过公司内部的技术交流小组的探讨后,不少小伙伴觉得这个

Android Jetpack架构组件:一文带你了解Lifecycle(使用篇)

前言 这一篇文章来介绍Android Jetpack架构组件的Lifecycle,Lifecycle用于帮助开发者管理Activity和Fragment 的生命周期,由于Lifecycle是LiveData和ViewModel的基础,所以需要先学习它. 1.为什么需要Lifecycle 在应用开发中,处理Activity或者Fragment组件的生命周期相关代码是必不可免的, 官方文档中举了一个例子,这里简化一下,在Activity中写一个监听,在Activity的不同生命周期方法中调用这个监听

Android 四大组件 与 MVC 架构模式

作为一个刚从JAVA转过来的Android程序员总会思考android MVC是什么样的? 首先,我们必须得说Android追寻着MVC架构,那就得先说一下MVC是个啥东西! 总体而来说MVC不能说是一个设计模式,因为划分维度太大,所以MVC应该属于架构模式! 百度百科 —— MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑和数据显示分离的方法组织代码,将业务逻辑被聚集到一个部件

Android官方架构组件:Lifecycle详解&amp;迪士尼彩乐园网站架设原理分析

我们先将重要的这些类挑选出来: LifecycleObserver接口( Lifecycle观察者):实现该接口的类,通过注解的方式,可以通过被LifecycleOwner类的addObserver(LifecycleObserver o)方法注册,被注册后,LifecycleObserver便可以观察到LifecycleOwner的生命周期事件. LifecycleOwner接口(Lifecycle持有者):实现该接口的类持有生命周期(Lifecycle对象),该接口的生命周期(Lifecyc

Android官方架构组件:Lifecycle详解&amp;迪士尼彩乐园定制开发原理分析

Lifecycle 是一个类,它持有关于组件(如 Activity 或 Fragment)生命周期状态的信息,并且允许其他对象观察此状态. 我们只需要2步: 1.Prestener继承LifecycleObserver接口public interface IPresenter extends LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) void onCreate(@NotNull LifecycleOwner

App 组件化/模块化之路——Android 框架组件(Android Architecture Components)使用指南

面对越来越复杂的 App 需求,Google 官方发布了Android 框架组件库(Android Architecture Components ).为开发者更好的开发 App 提供了非常好的样本.这个框架里的组件是配合 Android 组件生命周期的,所以它能够很好的规避组件生命周期管理的问题.今天我们就来看看这个库的使用. 通用的框架准则 官方建议在架构 App 的时候遵循以下两个准则: 关注分离 其中早期开发 App 最常见的做法是在 Activity 或者 Fragment 中写了大量

2.0.Architecture components架构组件

参考 https://developer.android.com/topic/libraries/architecture/ Architecture架构组件 架构组件是Jeppack中的一组支持库,主要用于帮助开发者构建一个健壮的架构. 很早就接触这个,但一直用的云里雾里的,年前和最近一段时间把官方文档和源码全都过了一遍,算是理解更深入了, 之后的几篇相关文章我不只是把用法列出来,会把一些源码分析做一些说明. Data Binding Declaratively bind observable