我的编程空间,编程开发者的网络收藏夹
学习永远不晚

ViewModel如何使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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<List<User>> users;     public LiveData<List<User>> getUsers() {           if(users == null) {               users= new MutableLiveData<List<Users>>();               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<String, ViewModel> 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如何使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

ViewModel如何使用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

ViewModel如何使用

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

Android 中ViewModel组件如何使用

本篇文章给大家分享的是有关Android 中ViewModel组件如何使用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1. 依赖库implementation "androi
2023-06-05

Android Jetpack组件之ViewModel如何使用

本文小编为大家详细介绍“Android Jetpack组件之ViewModel如何使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android Jetpack组件之ViewModel如何使用”文章能帮助大家解决疑惑,下面跟着小编的思路
2023-07-05

KotlinJetpack组件ViewModel使用详解

作为Jetpack组件之一的ViewModel,也是框架MVVM中的一部分,其功能主要用于屏幕反转后的数据保存;因为Activity翻转屏幕后或实现onCreat()方法,也就是说会重新创建页面,之前页面的临时数据都会清除
2022-12-08

AndroidJetpack组件之ViewModel使用详解

Android中的ViewModel是一个可以用来存储UI相关的数据的类。ViewModel的生命周期会比创建它的Activity、Fragment的生命周期长,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
2023-05-14

Android开发Jetpack组件ViewModel使用讲解

这篇文章主要介绍了AndroidJetpack架构组件ViewModel详解,ViewModel类让数据可在发生屏幕旋转等配置更改后继续存在,ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据。感兴趣可以来学习一下
2022-11-13

【Jetpack】ViewModel 架构组件 ( 视图 View 和 数据模型 Model | ViewModel 作用 | ViewModel 生命周期 | 代码示例 | 使用注意事项 )

文章目录 一、Activity 遇到的问题二、视图 View 和 数据模型 Model三、ViewModel 架构组件作用四、ViewModel 代码示例1、ViewModel 视图模型2、Activity 组件3、UI 布局文件4
2023-08-16

源码解析AndroidJetpack组件之ViewModel的使用

Jetpack是一个丰富的组件库,它的组件库按类别分为4类,分别是架构(Architecture)、界面(UI)、行为(behavior)和基础(foundation)。本文将从源码和大家讲讲Jetpack组件中ViewModel的使用
2023-05-17

ViewModel中StateFlow和SharedFlow单元测试使用详解

这篇文章主要为大家介绍了ViewModel中StateFlow和SharedFlow单元测试使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-17

【Android】怎么使用一个ViewModel用在多个Activity或者Fragment中

项目需求 在多个Activity或者Fragment中使用同一个ViewModel 需求实现 1.使用ActivityScope或FragmentScope 想在一个Activity或Fragment中共享ViewModel实例,可以使用A
2023-08-18

Android Jetpack 从使用到源码深耕【ViewModel从实践到原理 】(一)

五一期间,我们来一起学习总结一下Jetpack的ViewModel组件,从使用、源码、经验来总结分析。 Android Jetpack 从使用到源码深耕【ViewModel从实践到原理 】(一) Android Jetpack 从使用
2023-08-17

crystaldiskinforh如何使用

这篇文章主要介绍“crystaldiskinforh如何使用”,在日常操作中,相信很多人在crystaldiskinforh如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”crystaldiskinfo
2023-02-09

pandas如何使用

小编给大家分享一下pandas如何使用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、生成数据表 1、首先导入pandas库,一般都会用到numpy库,所以我们
2023-06-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录