Android开发 了解ViewModel
前言
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的更多相关文章
- android开发基础(ViewModel)
今天学习了ViewModel,其是Jetpack的一个类,它可以将界面中的数据独立出来,这样不会造成页面上信息的丢失. 我跟着视频做了一个简单的实例: 首先创建项目的时候它和以往的项目会有些不一样,因 ...
- Android开发总结
出来工作半年多了,没啥好交代的,就说说自己半年来的Android开发经历. 1.IDE 这半年来,从Eclipse到Android Studio,经历了两个IDE,在这里做一下简单的评价. ...
- Android开发利器之Data Binding Compiler V2 —— 搭建Android MVVM完全体的基础
原创声明: 该文章为原创文章,未经博主同意严禁转载. 前言: Android常用的架构有:MVC.MVP.MVVM,而MVVM是唯一一个官方提供支持组件的架构,我们可以通过Android lifecy ...
- Android 开发技术周报 Issue#277
新闻 Android 11界面再调整:加入快速截屏.多任务向国产ROM看齐 最新版Android 11推送 谷歌Pixel 5被曝光:支持反向充电 4月Android系统版本分布:8.0 Oreo最主
- 【Android开发高手笔记】Dagger2和它在SystemUI上的应用
和人类需要群居一样,程序界的进程.线程也需要通信往来.它们的交流则依赖模块之间.文件之间产生的关系.如何快速地搞清和构建这种关系,同时还能减轻彼此的依赖,需要开发者们认真思考. 我们将这种需求称之为依 ...
- 优秀Android开发简历都是这么写,你学会也可以进大厂
最近收了很多程序员的简历,工作经验从1年到十几年不等.发现一个问题,工作经验范围差不多的程序员,简历看起来也差不多... 为啥程序员的简历如此统一?正好最近看到一个分享也分析了这个问题,结合我个人的一 ...
- 我们是Android开发,我们都有着光明的未来
作为一名程序员经常会逛v2ex论坛,前几天逛着玩的时候忽然发现一篇文章,标题非常吸引眼球名字叫中年危机的终极解法,作为一个步入而立之年的老人,心里非常激动,到底是啥解决法呢,于是迅速点进去查看. 进去 ...
- 如何看待Android开发的“前景和内卷”
我们首先来意淫一波 5G时代Android即将崛起,Android将与物联网强强联合,配合上5G信息高速传递的模式,再搭配物联网号召的"万物互通"的旗号,同时各位Android开发 ...
- 大厂需要什么样的 Android 开发?
前言 昨天和一个百度的朋友闲聊,他说根据最近招聘 Android工程师的经验来看,大部分候选人在工作 3 年的时候基本都会遇上一道难过的坎. 为啥这么说呢? 因为工作一段时间之后,大部分工程师都已经完 ...
随机推荐
- leetcode.字符串.125验证回文串-Java
1. 具体题目 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写.说明:本题中,我们将空字符串定义为有效的回文串. 示例 1: 输入: "A man, a pl ...
- Python的datetime模块使用
两个常量 MAXYEAR:9999 MINYEAR:1 五个类 datetime.datetime:日期时间类 datetime.date:日期类 datetime.time:时间类 datetime ...
- HXY烧情侣
题目描述 众所周知,HXY已经加入了FFF团.现在她要开始喜(sang)闻(xin)乐(bing)见(kuang)地烧情侣了.这里有n座电影院,n对情侣分别在每座电影院里,然后电影院里都有汽油,但是要 ...
- 要素选择变化事件 IActiveViewEvents_SelectionChanged
void IDockableWindowDef.OnCreate(object hook) { m_application = hook as IApplication; m_hookHelper = ...
- span里面插入文字
.text-box span::before{ content:attr(data-text);}
- (Struts2学习系列三)Struts2动态方法调用:通配符方式
更改src/struts2.xml的代码: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ...
- Level DB 小调研
一. 概况: 1. 背景: 随着信息技术的高速发展,数据存储量和流量呈现爆炸式增长.目前百度统计日 PV(日点击量)已超过 75 亿次,中国网民在百度上进行50 亿次的搜索请求,百度贴吧日 PV 十亿 ...
- idea 在新建一个class的时候可以选择继承的父类
1.把光标放在父类名称上按alt+enter可以生成子类 2. 选中implement abstract class
- windows常用
host文件位置:C:\Windows\System32\drivers\etc
- 帝国cms过滤采集内容
在过滤广告正则的[!--ad--]标识处,加上过滤正则即可 https://jingyan.baidu.com/article/c275f6bae3ea0de33d75671c.html