千家信息网

ViewModel如何使用

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要介绍"ViewModel如何使用",在日常操作中,相信很多人在ViewModel如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"ViewModel如何
千家信息网最后更新 2026年11月02日ViewModel如何使用

这篇文章主要介绍"ViewModel如何使用",在日常操作中,相信很多人在ViewModel如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"ViewModel如何使用"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1 主要功能

  • Activity、Fragment存活期间的数据存储;

  • bind同一Activity的多个Fragment间数据共享;

  • 独立或与LiveData配合实现代码解耦;

2 使用方法

1) 引入ViewModel

  1. 在build.gradle中添加编译lifecycle.extensions module,该module同时包含ViewModel和LiveData:

compile('android.arch.lifecycle:extensions:1.0.0')

由于lifecycle.extensions内部依赖26.1.0版本的support_v7包,建议将工程中已引用的support_v7组件版本也升级到26.1.0或以上。

2) 构造数据对象

  1. 自定义ViewModel类,继承ViewModel;

  2. 在自定义的ViewModel类中添加需要的数据对象;

public class DemoViewModel extends ViewModel {     final public DemoData mData = new DemoData();     public DemoViewModel() {} }

3) 获取数据

  1. 通过ViewModelProviders和Activity / Fragment获取ViewModelProvider;

  2. 通过ViewModelProvider和自定义ViewModel类获取自定义ViewModel对象;

  3. 从自定义ViewModel对象获取数据对象,进行需要的读写操作。

DemoData data = ViewModelProviders.of(getActivity())         .get(DemoViewModel.class)        .mData; data.doSth();

3 使用场景示范

1) 单Activity多Fragment间数据维护

  • 需求点:

    • bind同一个Activity的Fragment A、B;

    • Fragment A、B间存在跳转关系;

    • Fragment A、B共同维护一些数据,且A、B均有读取、修改的业务需求;

  • 传统实现方法1:Intent +onFragmentResult()
    大致流程:

    • 跳转时需要将数据按k-v封装入Bundle,或者将数据Parcelable传递给下个页面;

    • 下个页面修改数据并返回后,需要从onFragmentResult()的Intent解析并同步数据;

    • Intent传递的数据大小总量不能超过1M;

麻烦且数据大小有限制。

  • 传统实现方法2:数据对象SingleInstance、static
    缺点:

    • 数据的生命周期要自行控制;

    • 容易内存泄漏;

同样麻烦,且有一定风险。

ViewModel同时规避了传统方法的缺点:

  • bind同一个Activity的Fragments均可以通过ViewModelProvider获取共同的数据对象,无需主动进行数据传递;

  • 脱离Intent、Bundle、Parcelable这些用起来很麻烦的控件;

  • 数据生命周期由ViewModel内部掌控,无需手动管理销毁;

2) 与LiveData配合实现UI、业务逻辑分层

同为官方架构组件的LiveData,功能是监听数据变化,并回调给注册的observer。ViewModel+LiveData可以很方便的抽象出数据层和业务层,快速解耦。
下面的Demo来自官方案例。通过Demo,以及LiveData、ViewModel同处一个module,可以看出官方非常建议两者搭配使用。再配合以往的Data-Binding,可以快速搭建起一套简易的MVVM业务体系。

public class MyViewModel extends ViewModel {     private MutableLiveData> users;     public LiveData> getUsers() {           if(users == null) {               users= new MutableLiveData>();               loadUsers();          }          return users;      }     private void loadUsers() {             //Do an asyncronous operation to fetch users.     } } 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 thefirst activity.           MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);           model.getUsers().observe(this,users -> {                 //update UI           });     } }

4 生命周期特性

ViewModel的生命周期与Lifecycle同步,当Activity /Fragment超出Lifecycle范围(并不是onDestroy()回调),ViewModel连同其包含的数据一起被销毁了。具体有多大呢,按照官方说法:

in the case of an activity, when it finishes, whilein the case of a fragment, when it's detached.

Activity退栈后(Fragment则是与Activity解除关系后),ViewModel就解除引用关系,准备被系统回收了。

5 源码分析

带着两个小问题简单的进行下源码分析:

1) ViewModel与Activity / Fragment的映射关系是如何建立起来的?

(以Activity为例)

第一部分:获取ViewModelProvider

  • 调用ViewModelProviders.of(Activity);

  • 一路调用,最终走到HolderFragmentManager.holderFragmentFor(Activity);

  • HolderFragmentManager依次从FragmentManager和HolderFragmentManager持有的HashMap查找:该Activity是否有HolderFragment与之映射(HolderFragment的作用下面一个问题将谈到);

HolderFragment.class HolderFragment holderFragmentFor(FragmentActivity activity) {      FragmentManagerfm = activity.getSupportFragmentManager();      HolderFragment holder = findHolderFragment(fm);      if(holder != null) {             return holder;       }else {             holder = (HolderFragment)this.mNotCommittedActivityHolders.get(activity);             if(holder != null) {                   return holder;             }else {                  //创建HolderFragment
  • 有则返回该HolderFragment;没有则创建一个HolderFragment:

    1. 新建一个HolderFragment,commit给FragmentManager,并存入HashMap以标记为not committed状态,防止重复commit;

    2. 向Application注册对该Activity的生命周期监听。如果HolderFragment尚未create,Activity就已经销毁,则从HashMap中移除该Activity,防止泄露;

    3. HolderFragment成功创建后,从HashMap中移除该Activity;

  • 使用HolderFragment持有的ViewModelStore对象完成ViewModelProvider的创建;

第一部分的职责是构建 / 查找HolderFragment,对构建过程中的异常做保护,最后返回ViewModelProvider。HolderFragment和ViewModelProvider共同持有的ViewModelStore将成为第二部分的核心;

(第二部分:获取ViewModel)

  • 调用ViewModelProvider.get(ViewModel.class);

  • 通过ViewModel的规范名(canonical name),从HashMap中查找是否已经存在该ViewModel的实例。有则返回;没有则通过反射构建一个,并存入HashMap;

ViewModelStore.class public class ViewModelStore {   private final HashMap mMap = new HashMap();

第二部分职责是映射,通过类名从HashMap查找ViewModel实例。整个映射逻辑也可以简化为:通过Activity类名找ViewModel实例;

2) ViewModel的生命周期如何管理?

ViewModel objects are scoped to the Lifecycle passed to the ViewModelProvider when getting the ViewModel.

看到官方文档中的这句话,心想ViewModel莫非是通过同为官方架构组件的Lifecycle来管理的生命周期的?
其实并没有那么复杂,ViewModel在第一次调用ViewModelProvider.get(ViewModel.class)创建;而销毁就需要靠HolderFragment自己的onDestroy()回调:

HolderFragment.class public void onDestroy() {         super.onDestroy();                this.mViewModelStore.clear();}
ViewModelStore.class public final void clear() {         Iteratorvar1 = this.mMap.values().iterator();         while(var1.hasNext()){             ViewModel vm = (ViewModel)var1.next();             vm.onCleared();        }         this.mMap.clear();    }

HolderFragment销毁后,调用ViewModelStore.clear(),清理HashMap对ViewModel对象的引用,待系统GC回收ViewModel。这也解释了创建ViewModelProvider时为什么需要HolderFragment配合,HolderFragment掌控了ViewModel的生命周期。

6 Last but not least

简述下官方架构中各组件的主要职责:

  • Lifecycle:将Activity /Fragment生命周期回调事件向外抛出;

  • LiveData:在Lifecycle范围内监听数据的变化;

  • ViewModel:在Lifecycle范围内存储和共享数据;

  • Room:简化Db操作;

除了Room,可以感受到官方在尽力把大家从最初的MVC往MVVM引导,更加强大的官方组件将使UI-业务-数据的抽象过程变得更加简单顺滑。

到此,关于"ViewModel如何使用"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

数据 周期 官方 对象 生命 业务 方法 组件 学习 传统 实例 架构 职责 范围 问题 麻烦 二部 监听 管理 内存 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 深圳市人人互联网科技有限公司 互联网科技公司华为 科技互联网政务服务 互联网扶贫科技 互联网金融 金融科技 猫创互联网科技 互联网高科技股票 四川狮子座互联网科技 衡水科技产业互联网平台 互联网和高科技公司 西藏七维空间互联网科技有限公司 互联网公司科技股 岳阳华臻互联网科技有限公司 朱啸虎曾投资哪些互联网科技企业 黑云互联网科技有限公司 上海同邻互联网科技有限公司规模 江苏互联网智能科技产品出厂价 云南互联网科技学费 数字互联网科技有限公司 宁波允成互联网科技有限公司 中关村互联网 科技集团 北京互联网科技有限公司 恒生科技互联网指数分析 银川新华互联网科技学校地址 武汉健翔互联网络科技有限公司 宜昌元轩互联网科技有限公司 天津腾达互联网科技有限公司 银川新华互联网科技学校原画 互联网科技的前景 互联网科技创业计划的风险分析
0