ViewModel,MVVM框架中的一部分,他主要作用是处理业务逻辑、数据分配等,他是Mode和VIew连接的桥梁,和MVP相比,他类似P。
ViewModel类有如下优点:
  1. ViewModel类是具有生命感知的能力,与和他绑定的Activity一样的生命周期,它可以解决请求网络时,Activity被突然销毁造成一些不必要的麻烦。
  2. 设备信息发生变更数据不会丢失(切横竖屏),其实它只有一个生命周期,检测页面销毁时触发
  3. ViewModel 的另一个特点就是同一个 Activity 的 Fragment 之间可以使用ViewModel实现共享数据。
  4. 每个Activity绑定的ViewModel都是独立的(Activity之间)

没用的小忠告

有些问题,可能没有深度。
有一次一个面试官问我,Q:你知道ViewModel是如何和Acvitity绑定的吗?我当时大脑在想1、他是不是问我内部实现?2、简单用法?我猜是第一,不然第二种的话,有啥可问的。当时我说:我不知道。他诧异的看着我,你不是使用过MVVM框架吗?不知道怎么用ViewModel吗。我不自信的说了句是通过ViewModelProvider。他来了一句是,是这个,后面问了我好多很简单的问题,当时给我整无语了,怎么全是这咋用,那咋用,一点深度都没有,却给我搞的很不自信,因为好多使用步骤平常不复习,就很容易忘,我当时就觉得这小子水平估计也不咋样,离场后果断删除了他们人事的联系方式。
 

1、开始使用

添加依赖

以前是需要添加依赖的,现在
方式一: implementation 'androidx.appcompat:appcompat:1.2.0',//这里面也包含ViewModel,LiveData等, 方式二: 也可以单独添加
implementation "androidx.fragment:fragment:1.1.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:2.1.0"
implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"

2、Activity

2.1、新建ViewModel

public class MyViewModel extends ViewModel {

    @Override
protected void onCleared() {
super.onCleared();
}
}
onCleared方法是ViewModel独有的,当Activity销毁后,它会调用,所以我们可以在这取消网络请求等。平常开发中不做任何操作时,如果有网络请求中,Activity被销毁,那么极有可能请求成功返回结果到activity中造成泄漏等不必要的麻烦。

解决方式:

可以使用ViewModel,结合onCleared(),call.cancel()等去做。
网络请求时,突然销毁activity,那么与之绑定的viewmodel也会销毁,同时我们在onCleared()方法中取消网络连接接口(call.cancel()),就算是有数据返回,activity也不会收到通知,因为数据是从livedata中监听的,只有livedata触发了更新,Activity才会收到通知。
(当然还有很多其他方式)
 

2.2、绑定Activity

这里有如下方式:
  • ViewModelProviders.of(this).get(class)(过时)
  • new ViewModelProvider(this,factory).get(class)(常用)
  • new ViewModelProvider.NewInstanceFactory().create(class);
 

第一种方式:ViewModelProviders.of(this).get(class)

ViewModelProviders.of(this).get(MyViewModel.class);

implementation "androidx.fragment:fragment:1.1.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:2.1.0"
implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"
这种方式是这些依赖中的,当然,如果你的和我的不一样,也无所谓,这不是重点。这个方式比较老了,在源码中也能发现,ViewModelProviders的of方法其实也是调用了ViewModelProvider,自动创建了一个factory。
----------------ViewModelProviders.class----------------

@NonNull
@MainThread
public static ViewModelProvider of(@NonNull Fragment fragment, @Nullable Factory factory) {
Application application = checkApplication(checkActivity(fragment));
if (factory == null) {
factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
}
return new ViewModelProvider(fragment.getViewModelStore(), factory);
}
 
 

第二种方式:new ViewModelProvider(this,factory).get(class)

ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class);
传入一个系统的factory。create是创建一个新的实例,而get是先从HashMap中找,找不到就创建新的实例。也是为什么重建的Viewmodel是同一个对象的原因,他会把对象放在ViewModelStore类中HashMap<String, ViewModel> mMap = new HashMap<>();中。这个方式比较新,一般也是这样创建。
 
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
//第一步:先查找
ViewModel viewModel = mViewModelStore.get(key); if (modelClass.isInstance(viewModel)) {
//noinspection unchecked
return (T) viewModel;
} else {
//noinspection StatementWithEmptyBody
if (viewModel != null) {
// TODO: log a warning.
}
}
//第二步:没有则创建,并保存在mViewModelStore中
if (mFactory instanceof KeyedFactory) {
viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
} else {
viewModel = (mFactory).create(modelClass);
}
mViewModelStore.put(key, viewModel);
//noinspection unchecked
return (T) viewModel;
}

第三种方式:new ViewModelProvider.NewInstanceFactory().create(class);

MyViewModel myViewModel1 = new ViewModelProvider.NewInstanceFactory().create(MyViewModel.class);
 
 
下面写一个LiveData,如果对LiveData不懂的可以翻看之前的博客,目录在顶部
public class MyViewModel extends ViewModel {
private MutableLiveData<String> mStr= new MutableLiveData<>(); public MutableLiveData<String> getmStr() {
return mStr;
}
public void setmStr(String s) {
if(mStr==null){
mStr = new MutableLiveData<>();
}
mStr.setValue(s);
}
@Override
protected void onCleared() {
super.onCleared();
}
}
全部代码
public class JPackActivity extends AppCompatActivity {

    private ActyJpackLayoutBinding mBinding;
private MyViewModel myViewModel; @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//通过databinding 把activity和view绑定
mBinding = DataBindingUtil.setContentView(this,R.layout.acty_jpack_layout);
//通过ViewModeProvider 把activity和ViewModel绑定起来。
myViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class); myViewModel.getmStr().observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
mBinding.textShow.setText(s);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
//移除观察者 }
 

3、Fragment

使用和Activity中一样。不过需要注意的是传入this和getActivity的区别
  • this:这个ViewModel是独立的,只为这个Fragment单独服务,其他Fragment无法获取到相同内存地址的ViewModel
  • getActivity:使用getActivity()获得的ViewModel 作用域在Activity里和所有他创建碎片的里,意思是你在其他Fragment也获取相同内存地址的ViewModel
 
 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
MyViewModel myViewModel = new ViewModelProvider(getActivity(), new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class);
return inflater.inflate(R.layout.fragment_blank, container, false);
}
 
当然还有一个注意点get("key1",MyViewModel.class);,get方法可以传key值,不同的key创建的ViewModel数据是独立的
 

4、总结

使用起来非常简单,还要多加练习,才不会被那些xx面试官问步骤咋实现难住。
 

Android  JetPack~ ViewModel (一)   介绍与使用的更多相关文章

  1. 学习Android Jetpack? 入门教程和进阶实战这里全都有!

    前言 2018年谷歌I/O,Jetpack横空出世,官方介绍如下: Jetpack 是一套库.工具和指南,可帮助开发者更轻松地编写优质应用.这些组件可帮助您遵循最佳做法.让您摆脱编写样板代码的工作并简 ...

  2. Android Jetpack 组建介绍(一)——Lifecycler

    转自带你领略Android Jetpack组件的魅力 Android Jetpack 对于任何一个产品来说,我们开发中都会面对哪些问题?如:产品交互.用户体验.代码结构.数据获取.数据存储.网络优化. ...

  3. Android Jetpack 组建介绍(二)——Lifecycler

    参考Android Jetpack架构组件之 Lifecycle(源码篇) 源码分析 关于Lifecycle的使用考上一篇文章Android Jetpack框架之 Lifecycles(使用篇),从使 ...

  4. Android Jetpack从入门到精通(深度好文,值得收藏)

    前言 即学即用Android Jetpack系列Blog的目的是通过学习Android Jetpack完成一个简单的Demo,本文是即学即用Android Jetpack系列Blog的第一篇. 记得去 ...

  5. Android Jetpack 架构组件最佳实践之“网抑云”APP

    背景 近几年,Android 相关的新技术层出不穷.往往这个技术还没学完,下一个新技术又出来了.很多人都是一脸黑人问号? 不少开发者甚至开始哀嚎:"求求你们别再创造新技术了,我们学不动了!& ...

  6. Android官方架构组件介绍之LifeCycle(一)

    Android官方架构组件介绍之LifeCycle 下面是官方提供的Android App开发的架构图: 从上图可以看到一些关键字:ViewModel,LiveData,Room等.其实看了上面视频的 ...

  7. Android Jetpack - 使用 Navigation 管理页面跳转

    在今年的 IO 大会上,发布了一套叫 Android Jetpack 的程序库.Android Jetpack 里的组件大部分我们都接触过了,其中也有一些全新的组件,其中一个就是 Navigation ...

  8. 带你了解Android Jetpack

    1.Jetpack主要特性有以下三点: 1.加速开发组件可单独使用,也可以协同工作,当使用kotlin语言特性时,可以提高效率. 2.消除样板代码Android Jetpack可管理繁琐的Activi ...

  9. Android Jetpack组件

    带你领略Android Jetpack组件的魅力 Android新框架jetpack的内容讲解:Room.WorkManager.LifeCycles.LiveData.ViewModel.DataB ...

  10. 【Android Jetpack高手日志】DataBinding 从入门到精通

    前言 DataBinding 数据绑定库是 Android Jetpack 的一部分,借助该库可以使用声明性格式(而非程序化地)将布局中的界面组件绑定到应用中的数据源.我个人觉得,使用 DataBin ...

随机推荐

  1. Python3.7.3安装TensorFlow和OpenCV3

    根据python的版本进行下载相应的文件 一.安装TensorFlow 进入网址https://pypi.org/project/tensorflow/#files下载TensorFlow文件 进入下 ...

  2. @Transactional注解事务失效的几种场景及原因

    1. 介紹 在业务开发的许多场景中,我们会使用到通过事务去控制多个操作的一致性.比较多的就是通过声明式事务,即使用 @Transactional 注解修饰方法的形式.但在使用过程中,要足够了解事务失效 ...

  3. input、print、字符串格式化输出

    1.使用input(), print()进行用户交互 """ 以前银行取钱只能拿着存折去柜台跟小姐姐交流才可以 你想干嘛 我想取钱 请输入密码 滴滴滴密码 想取多少钱 我 ...

  4. Vm无法连接到虚拟机,请确保您有权限运行该程序、访问该程序使用的所有目录以及访问所有临时文件目录,未能将管道连接到虚拟机:所有的管道范例都在使用中解决方法

    可能是杀掉进程导致 解决办法: 1.首先杀掉所有VM打头的任务. 2.删掉所有lck文件 3.VM文件夹内有一串很长的数字命名的文件夹或文件,删掉 4.发现被VMware-vmx.exe占用 5.打开 ...

  5. week_7

    Andrew Ng 机器学习笔记 ---By Orangestar Week_7 This week, you will be learning about the support vector ma ...

  6. 3、mysql着重号解决关键字冲突

    1.着重号(`  `): 使用着重号(` `)将字段名或表名括起来解决冲突:保证表中的字段.表名等没有和保留字.数据库系统名或常用方法名冲突

  7. 3D视觉算法初学概述

    背景知识 RGB-D相机 一,基于3DMM的三维人脸重建技术概述 1.1,3D 人脸重建概述 1.2,初版 3DMM 二,视觉SLAM算法基础概述 2.1,视觉里程计 2.2,后端优化 2.3,回环检 ...

  8. [常用工具] dlib编译调用指南

    dlib是一个C++工具包(dLIB中也有Python接口,但是主要编程语言为C++),包含绝大多数常用的机器学习算法,许多图像处理算法和深度学习算法,被工业界和学术界广泛应用于机器人.嵌入式设备.移 ...

  9. [深度学习] imgaug边界框增强笔记

    imgaug边界框增强笔记主要是讲述基于imgaug库对目标检测图像的边界框进行图像增强.本文需要掌握imgaug库的基本使用,imgaug库的基本使用见[深度学习] imgaug库使用笔记. 文章目 ...

  10. 由char和byte的关系引申出去——总结一下java中的字符编码相关知识

    由char和byte的关系引申出去--总结一下java中的字符编码相关知识 一.字符编码 手持两把锟斤拷,口中直呼烫烫烫 ​   在文章伊始,先来复习一下计算机中关于编码的一些基础知识,着重理清以下几 ...