
前言
ViewModel 作为 Jetpack 中的明星组件,相信大家都对其有一定的了解。在 Google 的官方介绍中也详细的罗列了 ViewModel 的优点,如:
- 可以提供和管理UI界面数据。(将加载数据与数据恢复从 Activity or Fragment中解耦)
- 可感知生命周期的组件。
- 不会因配置改变而销毁。
- 可以配合 LiveData 使用。
- 多个 Fragment 可以共享同一 ViewModel。
- 等等等…
你也可以通过下列两个视频,更为详细的了解 ViewModel:
在本篇文章中,不会讲解 ViewModel 的使用方式及使用 ViewModel 的原因,而是着重于讲解 ViewModel 的原理。通过阅读本篇文章你能了解到:
- ViewModel 在 Activity 中的绑定过程。
- ViewModel 在 Activity 中不会因配置改变而销毁的原理。
- ViewModel 在 Fragment 中的绑定过程。
- ViewModel 在 Fragment 中不会因配置改变而销毁的原理。
- ViewMode 能在 Fragment 中共享的原理。
希望通过该篇文章,大家能对 ViewModel 有更深入的了解。
作者:AndyJennifer
链接:https://www.jianshu.com/p/39ef3e0a5829
ViewModel 与 Activity 的绑定过程
一般情况下使用 ViewModel,我们一般会先声明自己的 ViewModel,并在 Activity 中的 onCreate 方法中使用 ViewModelProviders 来创建 ViewModel。 如下代码所示:
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
在谷歌的最新代码中,不推荐使用
ViweModelProviders(注意是有s的呦),而是直接使用ViewModelProvider的构造函数来创建ViewModelProvider对象。
通过使用 ViewModelProviders 类的 of() 方法,我们会得到一个 ViewModelProvider 对象。如下代码所示:
public static ViewModelProvider of(@NonNull FragmentActivity activity) {
return new ViewModelProvider(activity);
}
ViewModelProvider 类需要我们传递 ViewModelStore 与 Factory 对象。其构造函数声明如下:
//使用ViewModelStoreOwner对象构造函数
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
: NewInstanceFactory.getInstance());
}
//使用ViewModelStoreOwner与Factory对象的构造函数
public ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory) {
this(owner.getViewModelStore(), factory);
}
//使用ViewModelStore与Factory对象的构造函数
public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {
mFactory = factory;
mViewModelStore = store;
}
在 ViewModelProvider 内部,拥有三种类型构造函数:
(ViewModelStoreOwner owner):- 该构造函数使用 owner 对象的
getViewModelStore()方法来获取ViewModelStore对象,如果传入的 owner 对象也实现了HasDefaultViewModelProviderFactory接口时,那么会调用getDefaultViewModelProviderFactory()方法获取 Factory。反之,使用内部静态的NewInstanceFactory对象来创建 Factory 对象。
- 该构造函数使用 owner 对象的
(ViewModelStoreOwner owner, Factory factory):- 该构造函数使用 owner 对象的
getViewModelStore()方法来获取ViewModelStore对象,使用传递的 Factory 对象
- 该构造函数使用 owner 对象的
(ViewModelStore store, Factory factory):- 使用
ViewModelStore与Factory对象的构造函数
- 使用
Factory 接口介绍
在 ViewModelProvider 中,Factory 主要用于创建 ViewModel,Factory 的声明如下:
public interface Factory {
/**
* 通过给定的Class对象创建ViewModel对象
* <p>
*
* @param modelClass 所需ViewModel的Class对象
* @param <T> ViewModel的泛型参数
* @return 新创建的ViewModel对象
*/
@NonNull
<T extends ViewModel> T create(@NonNull Class<T> modelClass);
}
通过实现 Factory 接口,我们可以实现自己想要的工厂以创建所需的 ViewModel。在 Android 中有多个类都实现了该接口(如 KeyedFactory, AndroidViewModelFactory),这里以默认的 NewInstanceFactory 为例:
public static class NewInstanceFactory implements Factory {
private static NewInstanceFactory sInstance;
@NonNull
static NewInstanceFactory getInstance() {
if (sInstance == null) {
sInstance = new NewInstanceFactory();
}
return sInstance;
}
@SuppressWarnings("ClassNewInstance")
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
try {
//默认使用对应ViewModel类无参的构造函数创建实例对象
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 会调用 ViewModel 的无参构造函数创建实例对象,当然如果你需要在 ViewModel 中使用其他参数,你也可以传递自定义的 Factory。
ViewModelStore 介绍
ViewModelStore 内部维护了一个 HashMap,其 key 为 DEFAULT_KEY + ViewModel的Class对象底层类规范名称,其 value 为对应 ViewModel 对象。每个 Activity 与 Fragment 都对应着一个 ViewModelStore ,用于存储所需的 ViewModel。ViewModelStore 类声明如下所示:
DEFAULT_KEY 值为:“androidx.lifecycle.ViewModelProvider.DefaultKey”
public class ViewModelStore {
private final HashMap<String, ViewModel> mMap = new HashMap<>();
final void put(String key, ViewModel viewModel) {
ViewModel oldViewModel = mMap.put(key, viewModel);
if (oldVi

本文详细探讨了Jetpack组件中的ViewModel,重点解析其与Activity和Fragment的绑定过程,以及在配置改变时如何保持存活。文章揭示了ViewModel在Activity和Fragment中的创建、恢复原理,以及如何在Fragment间共享数据。通过对Factory接口、ViewModelStore和FragmentManager的讲解,帮助读者深入了解ViewModel的工作机制。
4459

被折叠的 条评论
为什么被折叠?



