前言

  ViewModel是google推出的一个数据处理框架,ViewModel类是被设计用来以可感知生命周期的方式存储和管理 UI 相关数据ViewModel中数据会一直存活即使 activity configuration发生变化.另外它生来可能目的就是与Fragment在数据共享上进行配合的.

使用它常与LiveData数据前台类(类似观察者模式的数据实体回调类)进行配合以前使用,如果你未了解LiveData建议你先了解它Android开发 LiveData与MutableLiveData详解 然后在回头在来看这篇博客

  在总结下有的这些特征:

1.让数据与UI隔离:让ViewModel来获取数据加工数据并且回调给UI层.明确职责工作分离(参考MVP,MVVM这些框架结构)

2.数据与生命周期绑定:ViewModel与注册的Activity的生命周期绑定,有着与Activity同步的生命周期,如下图.这样就算网络请求的数据的异步回来后Activity已经销毁也不会出现问题,因为ViewModel也会被销毁终止数据的回调.

3.数据持久化:ViewModel不会因为屏幕的旋转导致Activity重新创建而重置数据.(这样避免了Activity被旋转数据丢失的问题)

4.与其他Activity独立:ViewModel的数据是独立的,它跟每一个绑定的Activity都是实例一个单独的数据(意思是它无法跟多个Activity绑定后同步共享数据)

5.天生为了配合Fragment:ViewModel可以与一个Activity与多个Fragment绑定后共享数据.(你终于可以不用很蛋疼的把Fragment的数据暂存到Activity里了)并且可以都与他们的生命周期关联.这样Fragment短暂的生命周期将不在让你烦恼数据的暂存问题.

依赖

    implementation "androidx.fragment:fragment:1.1.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:2.1.0"
implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"

androidx.lifecycle:lifecycle-extensions:2.1.0 是ViewModelProviders的实现依赖,如果不导入就没有这个。

创建与绑定Activity

创建ViewModel

public class DemoViewModel extends ViewModel {
// TODO: Implement the ViewModel @Override
protected void onCleared() {
super.onCleared();
//清除的方法,这个方法需要让你处理一些网络请求的停止或者数据加工的逻辑停止,它与绑定的Activity在销毁的时候触发.你不需要手动在Activity里调用它
}
}

绑定Activity

public class Demo1Activity extends AppCompatActivity {
private static final String TAG = "Demo1Activity";
private DemoViewModel mDemoViewModel; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
mDemoViewModel = ViewModelProviders.of(this).get(DemoViewModel.class);//获取ViewModel,让ViewModel与此activity绑定 }
}

以上简单继承和注册后就与Activity绑定了,它是单例模式的这点你可以在of()方法里看到它实现了单例(一个Activity只有一个单例),另外在Fragment的方式也是与Activity相同的方式如下:

mViewModel = ViewModelProviders.of(getActivity()).get(DemoViewModel.class);

这样你就将Activity和Fragment之间可以用ViewModel进行数据上的共享与同步了

简单的demo

  实际使用的时候是与LiveData一起配合使用的,这里提供一个简单的demo了解下实际使用.

创建LiveData类

public class DemoData extends LiveData<DemoData> {
private int tag1;
private int tag2; public int getTag1() {
return tag1; }
public void setTag1(int tag1) {
this.tag1 = tag1;
postValue(this);
} public int getTag2() {
return tag2;
} public void setTag2(int tag2) {
this.tag2 = tag2;
postValue(this);
}
}

创建ViewModel并且在内部实例化LiveData

public class DemoViewModel extends ViewModel {
// TODO: Implement the ViewModel
private DemoData mDemoData = new DemoData(); public DemoData getDemoData() {
return mDemoData;
} @Override
protected void onCleared() {
super.onCleared();
//清除的方法,这个方法需要让你处理一些网络请求的停止或者数据加工的逻辑停止
}
}

绑定Activity,模拟数据变化

public class Demo2Activity extends AppCompatActivity {
private static final String TAG = "Demo2Activity";
private Button mBtnAddData;
private DemoViewModel mDemoViewModel; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo2);
mBtnAddData = findViewById(R.id.btn_add_data);
mDemoViewModel = ViewModelProviders.of(this).get(DemoViewModel.class);//获取ViewModel,让ViewModel与此activity绑定
mDemoViewModel.getDemoData().observe(this, new Observer<DemoData>() { //注册观察者,观察数据的变化
@Override
public void onChanged(DemoData demoData) {
Log.e(TAG, "onChanged: 数据有更新");
}
}); mBtnAddData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e(TAG, "onClick: 已经点击");
mDemoViewModel.getDemoData().setTag1(123); //这里手动用按键点击更新数据 }
});
}
}

绑定Fragment

public class DemoFragment extends Fragment {
private static final String TAG = "DemoFragment";
private DemoViewModel mViewModel; @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.demo1_fragment, container, false);
} @Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// TODO: Use the ViewModel
mViewModel = ViewModelProviders.of(getActivity()).get(DemoViewModel.class);
mViewModel.getDemoData().observe(this, new Observer<DemoData>() {
@Override
public void onChanged(DemoData demoData) {
Log.e(TAG, "onChanged: 数据有更新"); }
}); }
}

Fragment绑定ViewModel , of(getActivity())与of(this)的区别

mViewModel = ViewModelProviders.of(getActivity()).get(DemoViewModel.class); //使用getActivity()获得的ViewModel 作用域在Activity里和所有他创建碎片的里,意思是你在其他Fragment也获取相同内存地址的ViewModel

mViewModel = ViewModelProviders.of(this).get(DemoViewModel.class); //这个ViewModel是独立的,只为这个Fragment单独服务,其他Fragment无法获取到相同内存地址的ViewModel

end

Android开发 了解ViewModel的更多相关文章

  1. android开发基础(ViewModel)

    今天学习了ViewModel,其是Jetpack的一个类,它可以将界面中的数据独立出来,这样不会造成页面上信息的丢失. 我跟着视频做了一个简单的实例: 首先创建项目的时候它和以往的项目会有些不一样,因 ...

  2. Android开发总结

    出来工作半年多了,没啥好交代的,就说说自己半年来的Android开发经历. 1.IDE      这半年来,从Eclipse到Android Studio,经历了两个IDE,在这里做一下简单的评价. ...

  3. Android开发利器之Data Binding Compiler V2 —— 搭建Android MVVM完全体的基础

    原创声明: 该文章为原创文章,未经博主同意严禁转载. 前言: Android常用的架构有:MVC.MVP.MVVM,而MVVM是唯一一个官方提供支持组件的架构,我们可以通过Android lifecy ...

  4. Android 开发技术周报 Issue#277

    新闻 Android 11界面再调整:加入快速截屏.多任务向国产ROM看齐 最新版Android 11推送 谷歌Pixel 5被曝光:支持反向充电 4月Android系统版本分布:8.0 Oreo最主

  5. 【Android开发高手笔记】Dagger2和它在SystemUI上的应用

    和人类需要群居一样,程序界的进程.线程也需要通信往来.它们的交流则依赖模块之间.文件之间产生的关系.如何快速地搞清和构建这种关系,同时还能减轻彼此的依赖,需要开发者们认真思考. 我们将这种需求称之为依 ...

  6. 优秀Android开发简历都是这么写,你学会也可以进大厂

    最近收了很多程序员的简历,工作经验从1年到十几年不等.发现一个问题,工作经验范围差不多的程序员,简历看起来也差不多... 为啥程序员的简历如此统一?正好最近看到一个分享也分析了这个问题,结合我个人的一 ...

  7. 我们是Android开发,我们都有着光明的未来

    作为一名程序员经常会逛v2ex论坛,前几天逛着玩的时候忽然发现一篇文章,标题非常吸引眼球名字叫中年危机的终极解法,作为一个步入而立之年的老人,心里非常激动,到底是啥解决法呢,于是迅速点进去查看. 进去 ...

  8. 如何看待Android开发的“前景和内卷”

    我们首先来意淫一波 5G时代Android即将崛起,Android将与物联网强强联合,配合上5G信息高速传递的模式,再搭配物联网号召的"万物互通"的旗号,同时各位Android开发 ...

  9. 大厂需要什么样的 Android 开发?

    前言 昨天和一个百度的朋友闲聊,他说根据最近招聘 Android工程师的经验来看,大部分候选人在工作 3 年的时候基本都会遇上一道难过的坎. 为啥这么说呢? 因为工作一段时间之后,大部分工程师都已经完 ...

随机推荐

  1. Java服务定位器模式

    当我们想要使用JNDI查找来定位各种服务时,使用服务定位器设计模式. 考虑到为服务查找JNDI的高成本,所以在服务定位器模式使用缓存技术. 首次需要服务时,服务定位器在JNDI中查找并缓存服务对象. ...

  2. nrm的安装使用

    1.利用npm来安装nrm,且是全局安装nrm包 npm i nrm -g 2.使用nrm ls查看当前所有可用的镜像源地址以及当前所使用的镜像源地址 3.使用nrm use npm 或者nrm us ...

  3. 认识AppDomain类

    原文:认识AppDomain类 表示应用程序域,它是一个应用程序在其中执行的独立环境. 创建新的 AppDomain,在该新建 AppDomain 中实例化类型,以及与该类型的对象通信. usingn ...

  4. C语言清空指针

    #include <stdio.h> int main() { /********************************************* * * %d int * %f ...

  5. QTableView排序

    1.由于是点击HeaderView进行排序,所以初始代码 //排序 //QTableView model->lgoods_model view->lgoods_view lgoods_he ...

  6. systemctl命令的使用及服务状态的查看

    二.systemctl命令 systemctl list-units            ##列出当前系统服务的状态 systemctl list-unit-files       ##列出服务的开 ...

  7. git使用ssh连接服务器

    git如何连接服务器呢? $ ssh -p 22 root@服务器ip 解释:ssh -p 端口号 登录的用户名@IP

  8. PHP 实现斐波那契数列

    使用循环实现 <?php $arr[1] = 1; for($i = 2;$i < 100;$i++) { $arr[$i] = $arr[$i-1] + $arr[$i-2]; } ec ...

  9. 单源最短路径问题2 (Dijkstra算法)

    用邻接矩阵 /* 单源最短路径问题2 (Dijkstra算法) 样例: 5 7 0 1 3 0 3 7 1 2 4 1 3 2 2 3 5 2 4 6 3 4 4 输出: [0, 3, 7, 5, 9 ...

  10. 分布式项目controller项目中web.xml配置文件的编写

    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" " ...