android 框架组件,剖析 Android 架构组件之 ViewModel

本文主要分析 ViewModel 的以下3个方面:获取和创建过程。

Configuration Changes 存活原理。

销毁过程。

1. 依赖库implementation "androidx.fragment:fragment:1.0.0"

implementation "androidx.lifecycle:lifecycle-viewmodel:2.0.0"

implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"

2. 主要类与接口import androidx.fragment.app.Fragment;

import androidx.fragment.app.FragmentActivity;

import androidx.lifecycle.ViewModel;

import androidx.lifecycle.AndroidViewModel;

import androidx.lifecycle.ViewModelProvider;

import androidx.lifecycle.ViewModelProvider.Factory;

import androidx.lifecycle.ViewModelProviders;

import androidx.lifecycle.ViewModelStore;

import androidx.lifecycle.ViewModelStoreOwner;

3. ViewModel

ViewModel 是一个抽象类,类中只定义了一个空实现的 onCleared() 方法。@SuppressWarnings()

{

}

}

3.1 AndroidViewModel

AndroidViewModel 类扩展了 ViewModel 类,增加了 Application 字段,在构造方法初始化,并提供了 getApplication() 方法。public class AndroidViewModel extends ViewModel{

private Application mApplication;

public AndroidViewModel(@NonNull Application application){

mApplication = application;

}

/**

* Return the application.

*/

@NonNull

public

4. 获取和创建过程分析

获取 ViewModel 对象代码如下:ViewModelProviders.of(activityOrFragment).get(ViewModel::class.java)

4.1 ViewModelProviders

ViewModelProviders 类提供了4个静态工厂方法 of() 创建新的 ViewModelProvider 对象。ViewModelProviders.of(Fragment)

ViewModelProviders.of(FragmentActivity)

ViewModelProviders.of(Fragment, Factory)

ViewModelProviders.of(FragmentActivity, Factory)

4.2 ViewModelProvider

ViewModelProvider 负责提供 ViewModel 对象,类中定义了以下两个字段:private final Factory mFactory;

private final ViewModelStore mViewModelStore;

先说说这两个类的功能。

4.3 ViewModelProvider.Factory

Factory 接口定义了一个创建 ViewModel 的接口 create(),ViewModelProvider 在需要时调用该方法新建 ViewModel 对象。public interface Factory {

Android 已经内置了2个 Factory 实现类,分别是:

AndroidViewModelFactory 实现类,可以创建 ViewModel 和 AndroidViewModel 子类对象。

NewInstanceFactory 类,只可以创建 ViewModel 子类对象。

它们的实现都是通过反射机制调用 ViewModel 子类的构造方法创建对象。public static class NewInstanceFactory implements Factory{

@Override

public

AndroidViewModelFactory 继承 NewInstanceFactory 类,是个单例,支持创建 AndroidViewModel 子类对象。public static class AndroidViewModelFactory extends ViewModelProvider.NewInstanceFactory{

private static AndroidViewModelFactory sInstance;

public static AndroidViewModelFactory getInstance(Application application){

if (sInstance == null) {

sInstance = new AndroidViewModelFactory(application);

}

return sInstance;

}

private Application mApplication;

public AndroidViewModelFactory(Application application){

mApplication = application;

}

@Override

public

4.4 ViewModelStore

ViewModelStore 类中维护一个 Mappublic class ViewModelStore{

private final HashMap mMap = new HashMap<>();

final void put(String key, ViewModel viewModel) {

ViewModel oldViewModel = mMap.put(key, viewModel);

}

final ViewModel get(String key) {

return mMap.get(key);

}

}

4.5 ViewModelStoreOwner

ViewModelStore 是来自于 FragmentActivity 和 Fragment,它们实现了 ViewModelStoreOwner 接口,返回当前 UI 作用域里的 ViewModelStore 对象。public interface ViewModelStoreOwner {

ViewModelStore getViewModelStore();

}

在 Fragment 类中的实现如下:public ViewModelStore getViewModelStore(){

if (getContext() == null) {

throw new IllegalStateException("Can't access ViewModels from detached fragment");

}

if (mViewModelStore == null) {

mViewModelStore = new ViewModelStore();

}

return mViewModelStore;

}

在 FragmentActivity 类中的实现如下:public ViewModelStore getViewModelStore(){

if (getApplication() == null) {

throw new IllegalStateException("Your activity is not yet attached to the "

+ "Application instance. You can't request ViewModel before onCreate call.");

}

if (mViewModelStore == null) {

mViewModelStore = new ViewModelStore();

}

return mViewModelStore;

}

4.6 创建 ViewModelProvider

回到 of() 方法的实现public static ViewModelProvider of(FragmentActivity activity, Factory factory) {

Application application = checkApplication(activity);

if (factory == null) {

factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);

}

return new ViewModelProvider(activity.getViewModelStore(), factory);

}

在创建 ViewModelProvider 对象时需要传入 ViewModelStore 和 Factory 对象。若 factory 为 null,将使用 AndroidViewModelFactory 单例对象。

4.7 获取 ViewModel 对象

调用 ViewModelProvider 对象的 get() 方法获取 ViewModel 对象,如果在 ViewModelStore 里不存在,则使用 Factory 创建一个新的对象并存放到 ViewModelStore 里。public  T get(String key, Class modelClass) {

ViewModel viewModel = mViewModelStore.get(key);

if (modelClass.isInstance(viewModel)) {

return (T) viewModel;

}

viewModel = mFactory.create(modelClass);

mViewModelStore.put(key, viewModel);

return (T) viewModel;

}

5. Configuration Changes 存活原理

当 Activity 或 Fragment 被系统重建时,ViewModel 对象不会被销毁,新的 Activity 或 Fragment 对象拿到的是同一个 ViewModel 对象。

在 FragmentActivity#onRetainNonConfigurationInstance() 方法中,会将 ViewModelStore 对象保留起来。public final Object onRetainNonConfigurationInstance(){

Object custom = onRetainCustomNonConfigurationInstance();

FragmentManagerNonConfig fragments = mFragments.retainNestedNonConfig();

if (fragments == null && mViewModelStore == null && custom == null) {

return null;

}

NonConfigurationInstances nci = new NonConfigurationInstances();

nci.custom = custom;

nci.viewModelStore = mViewModelStore;

nci.fragments = fragments;

return nci;

}

然后在 onCreate() 方法能获取之前保留起来的 ViewModelStore 对象。protected void onCreate(Bundle savedInstanceState){

mFragments.attachHost(null /*parent*/);

super.onCreate(savedInstanceState);

NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance();

if (nc != null) {

mViewModelStore = nc.viewModelStore;

}

// ...

}

那 Fragment 作用域里是如何实现的呢?在 FragmentActivity 的 onRetainNonConfigurationInstance() 方法中里有这样一句代码:FragmentManagerNonConfig fragments = mFragments.retainNestedNonConfig();

实现保留的机制是一样的,只不过放在 FragmentManagerNonConfig 对象中。是在 FragmentManager#saveNonConfig() 方法中将 ViewModelStore 对象保存到 FragmentManagerNonConfig 里的。void saveNonConfig(){

ArrayList

该方法的调用顺序是:FragmentActivity#onSaveInstanceState() -> FragmentManager#saveAllState() -> FragmentManager#saveNonConfig()。

6. 销毁过程

在 FragmentActivity 类的 onDestory() 方法中。@Override

protected void onDestroy(){

super.onDestroy();

if (mViewModelStore != null && !isChangingConfigurations()) {

mViewModelStore.clear();

}

mFragments.dispatchDestroy();

}

在 Fragment 类的 onDestory() 方法中。public void onDestroy(){

mCalled = true;

FragmentActivity activity = getActivity();

boolean isChangingConfigurations = activity != null && activity.isChangingConfigurations();

if (mViewModelStore != null && !isChangingConfigurations) {

mViewModelStore.clear();

}

}

先判断是否有发生 Configuration Changes,如果没有则会调用 ViewModelStore 的 clear() 方法,再一一调用每一个 ViewModel 的 onCleared() 方法。public final void clear(){

for (ViewModel vm : mMap.values()) {

vm.onCleared();

}

mMap.clear();

}

7. 总结

以上便是 ViewModel 3个主要过程的剖析,这里做一下总结。

通过 ViewModelProviders 创建 ViewModelProvider 对象,调用该对象的 get() 方法获取 ViewModel 对象。

当 ViewModelStore  里不存在想要的对象,ViewModelProvider 会使用 Factory 新建一个对象并存放到 ViewModelStore 里。

当发生Configuration Changes 时,FragmentActivity 利用 getLastNonConfigurationInstance()、onRetainNonConfigurationInstance() 方法实现 ViewModelStore 的保留与恢复,进而实现 ViewModel 对象的保活。

当 FragmentActivity 和 Fragment 被销毁时,会根据是否发生 Configuration Changes 来决定是否销毁 ViewModel。

作者:吴下阿吉

链接:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值