栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

学Android必知:Jetpack核心组件,ViewModel的使用及原理解析,牛笔了

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

学Android必知:Jetpack核心组件,ViewModel的使用及原理解析,牛笔了

当Activity或者Fragment创建了关联的ViewModel,那么该Activity或Fragment只要处于活动状态,那么该ViewModel就不会被销毁,即使是该Activity屏幕旋转时重建了。所以也可以拿来做数据的暂存。

ViewModel主要是拿来获取或者保留Activity/Fragment所需要的数据的,开发者可以在Activity/Fragment中观察ViewModel中的数据更改(这里需要配合LiveData食用)。

ps: ViewModel只是用来管理UI的数据的,千万不要让它持有View、Activity或者Fragment的引用(小心内存泄露)。

本文以由浅入深的方式学习ViewModel。

二、ViewModel的使用

引入ViewModel

//引入AndroidX吧,替换掉support包
implementation ‘androidx.appcompat:appcompat:1.0.2’

def lifecycle_version = “2.0.0”
// ViewModel and LiveData
implementation “androidx.lifecycle:lifecycle-extensions:$lifecycle_version”

简单使用起来

定义一个User数据类。

class User implements Serializable {

public int age;
public String name;

public User(int age, String name) {
this.age = age;
this.name = name;
}

@Override
public String toString() {
return “User{” +
“age=” + age +
“, name=’” + name + ‘’’ +
‘}’;
}
}

然后引出我们今天的主角ViewModel。

public class UserModel extends ViewModel {

public final MutableLiveData mUserLiveData = new MutableLiveData<>();

public UserModel() {
//模拟从网络加载用户信息
mUserLiveData.postValue(new User(1, “name1”));
}

//模拟 进行一些数据骚操作
public void doSomething() {
User user = mUserLiveData.getValue();
if (user != null) {
user.age = 15;
user.name = “name15”;
mUserLiveData.setValue(user);
}
}

}

这时候在Activity中就可以使用ViewModel了。其实就是一句代码简单实例化,然后就可以使用ViewModel了。

//这些东西我是引入的androidx下面的
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

public class MainActivity extends FragmentActivity {

private TextView mContentTv;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mContentTv = findViewById(R.id.tv_content);

//构建ViewModel实例
final UserModel userModel = ViewModelProviders.of(this).get(UserModel.class);

//让TextView观察ViewModel中数据的变化,并实时展示
userModel.mUserLiveData.observe(this, new Observer() {
@Override
public void onChanged(User user) {
mContentTv.setText(user.toString());
}
});

findViewById(R.id.btn_test).setonClickListener(new View.onClickListener() {
@Override
public void onClick(View view) {
//点击按钮 更新User数据 观察TextView变化
userModel.doSomething();
}
});
}
}

这个时候,我们点击一下按钮(user中的age变为15),我们可以旋转手机屏幕(这个时候其实Activity是重新创建了,也就是onCreate()方法被再次调用,但是ViewModel其实是没有重新创建的,还是之前那个ViewModel),但是当我们旋转之后,发现TextView上显示的age居然还是15,这就是ViewModel的魔性所在。

这个就不得不提ViewModel的生命周期了,它只有在Activity销毁之后,它才会自动销毁(所以别让ViewModel持有Activity引用啊,会内存泄露的)。 下面引用一下谷歌官方的图片,将ViewModel的生命周期展示的淋漓尽致。

ViewModel妙用1: Activity与Fragment"通信"

有了ViewModel,Activity与Fragment可以共享一个ViewModel,因为Fragment是依附在Activity上的,在实例化ViewModel时将该Activity传入ViewModelProviders,它会给你一个该Activity已创建好了的ViewModel,这个Fragment可以方便的访问该ViewModel中的数据。在Activity中修改userModel数据后,该Fragment就能拿到更新后的数。

ViewModel妙用2: Fragment与Fragment"通信"

下面我们来看一个例子(Google官方例子)

public class SharedViewModel extends ViewModel {
private final MutableLiveData selected = new MutableLiveData();

public void select(Item item) {
selected.setValue(item);
}

public LiveData getSelected() {
return selected;
}
}

public class MasterFragment extends Fragment {
private SharedViewModel model;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
itemSelector.setonClickListener(item -> {
model.select(item);
});
}
}

public class DetailFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
model.getSelected().observe(this, { item ->
// Update the UI.
});
}
}

1、首先定义一个ViewModel,在里面放点数据。

2、然后在MasterFragment和DetailFragment都可以拿到该ViewModel,拿到了该ViewModel就可以拿到里面的数据了,相当于间接通过ViewModel通信了。so easy…

三、ViewModel源码解析

我们从下面这句代码start.

final UserModel userModel = ViewModelProviders.of(this).get(UserModel.class);

我们跟着ViewModelProviders.of(this)打开新世界的大门。

ViewModelProviders.of(this) 方法


@MainThread
public static ViewModelProvider of(@NonNull FragmentActivity activity) {
return of(activity, null);
}

@MainThread
public static ViewModelProvider of(@NonNull FragmentActivity activity,
@Nullable Factory factory) {
//检查application是否为空,不为空则接收
Application application = checkApplication(activity);
if (factory == null) {
//构建一个ViewModelProvider.AndroidViewModelFactory
factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
}
return new ViewModelProvider(activity.getViewModelStore(), factory);
}

ViewModelProviders里面的of()函数其实是为了方便我们构建一个ViewModelProvider。而ViewModelProvider,一看名字就知道干啥的了,就是提供ViewModel的。

Factory是ViewModelProvider的一个内部接口,它的实现类是拿来构建ViewModel实例的。它里面只有一个方法,就是创建一个ViewModel。


@NonNull
T create(@NonNull Class modelClass);
}

Factory有2个实现类:一个是NewInstanceFactory,一个是AndroidViewModelFactory。

NewInstanceFactory源码

public static class NewInstanceFactory implements Factory {

@SuppressWarnings(“ClassNewInstance”)
@NonNull
@Override
public T create(@NonNull Class modelClass) {
//noinspection TryWithIdenticalCatches
try {
return modelClass.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
}
}
}

NewInstanceFactory专门用来实例化那种构造方法里面没有参数的class,并且ViewModel里面是不带Context的,然后它是通过newInstance()去实例化的。

AndroidViewModelFactory 源码

public static class AndroidViewModelFactory extends ViewModelProvider.NewInstanceFactory {

private static AndroidViewModelFactory sInstance;


@NonNull
public static AndroidViewModelFactory getInstance(@NonNull Application application) {
if (sInstance == null) {
sInstance = new AndroidViewModelFactory(application);
}
return sInstance;
}

private Application mApplication;


public AndroidViewModelFactory(@NonNull Application application) {
mApplication = application;
} 结尾

最后,针对上面谈的内容,给大家推荐一个Android资料,应该对大家有用。

首先是一个知识清单:(对于现在的Android及移动互联网来说,我们需要掌握的技术)

泛型原理丶反射原理丶Java虚拟机原理丶线程池原理丶
注解原理丶注解原理丶序列化
Activity知识体系(Activity的生命周期丶Activity的任务栈丶Activity的启动模式丶View源码丶Fragment内核相关丶service原理等)
代码框架结构优化(数据结构丶排序算法丶设计模式)
APP性能优化(用户体验优化丶适配丶代码调优)
热修复丶热升级丶Hook技术丶IOC架构设计
NDK(c编程丶C++丶JNI丶LINUX)
如何提高开发效率?
MVC丶MVP丶MVVM
微信小程序
Hybrid
Flutter

接下来是资料清单:(敲黑板!!!)

领取通道在这里给你们摆上了~

点击我的GitHub免费获取

1.数据结构和算法

2.设计模式

3.全套体系化高级架构视频;七大主流技术模块,视频+源码+笔记

4.面试专题资料包(怎么能少了一份全面的面试题总结呢~)

不论遇到什么困难,都不应该成为我们放弃的理由!共勉~

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。


片转存中…(img-2XbzueC0-1646564538796)]

3.全套体系化高级架构视频;七大主流技术模块,视频+源码+笔记

[外链图片转存中…(img-Vn8BDkOf-1646564538796)]

4.面试专题资料包(怎么能少了一份全面的面试题总结呢~)

[外链图片转存中…(img-9WNQbmE8-1646564538796)]

不论遇到什么困难,都不应该成为我们放弃的理由!共勉~

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。

[外链图片转存中…(img-MVVNOHBL-1646564538797)]

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/756367.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号