android Factory2,Android开发 ViewModel_2_了解多种的构建方式 (Factory 与 key)

前言

ViewModel的虽然可以以很简单的ViewModelProviders.of(getActivity()).get(ViewModel.class); 但是这只是google提供的简单构建,你需要引入下面的库才能使用:

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

但是!远远不止这样。ViewModel还可以自定义实例(其实自己实现实例构建ViewModel才是google推荐的,但是每次都要创建构建类非常麻烦,这些后面会提到)方式或者增加key来创建多个不同的ViewModel。

了解ViewModel的构建原理

因为后续的使用ViewModelProvider.Factory创建ViewModel,所以我们必需了解一些些ViewModel构建、保存、移除原理。好在有一个参照物可以阅读理解,那就是上面提到以ViewModelProviders形式的构建ViewModel。对照着它看基本上就能明白一些东西了。

看看 ViewModelProviders.of() 干了啥事情

我们点击进入源码后可以看到如下代码

@NonNull

@MainThreadpublic staticViewModelProvider of(@NonNull FragmentActivity activity) {return of(activity, null);

}

恩,of又去调用了一个重载的of,但是传入了一个activity或者Fragment 和 一个null ,我们看看这个2个参数的of干了什么

@NonNull

@MainThreadpublic staticViewModelProvider of(@NonNull FragmentActivity activity,

@Nullable Factory factory) {

Application application= checkApplication(activity); //源码在这里检查了一下activity的application

if (factory == null) {//它拿application去创建了一个Factory类//这个factory其实就是构建ViewModel的工厂类

factory =ViewModelProvider.AndroidViewModelFactory.getInstance(application);

}//实例化了一个ViewModelProvider,//在activity里取得ViewModelStore(这个东西是用于保存ViewModel使用的),也传入了//并且也把Factory类一起传入//其实ViewModelStore和factory传入后就直接成为成员变量缓存了,等待你调用get方法来创建ViewModel

return newViewModelProvider(activity.getViewModelStore(), factory);

}

我们可以看看ViewModelProvider.AndroidViewModelFactory.getInstance(application) 这行代码

private staticAndroidViewModelFactory sInstance;/*** Retrieve a singleton instance of AndroidViewModelFactory.

*

*@paramapplication an application to pass in {@linkAndroidViewModel}

*@returnA valid {@linkAndroidViewModelFactory}*/@NonNullpublic staticAndroidViewModelFactory getInstance(@NonNull Application application) {if (sInstance == null) {

sInstance= newAndroidViewModelFactory(application);

}returnsInstance;

}

可以看到,直接给你了一个有Application的全局单例的Factory类。

接下来看看ViewModelProviders.of(getActivity()).get()    get干了啥事

get()方法其实就是实现了factory 创建 与 ViewModelStore保存 ViewModel,并且返回ViewModel。 我们可以看看下面这些代码

@NonNull

@MainThreadpublic T get(@NonNull ClassmodelClass) {

String canonicalName= modelClass.getCanonicalName(); //获取了传入的实现的ViewModel的类名

if (canonicalName == null) {throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");

}//因为我们没有传入key,所以这里直接用类名取代的成为了key//然后就进入下面这个重载的get方法里进行实现了

return get(DEFAULT_KEY ":" canonicalName, modelClass);

}

@NonNull

@MainThreadpublic T get(@NonNull String key, @NonNull ClassmodelClass) {

ViewModel viewModel= mViewModelStore.get(key);//去查找这个ViewModelStore 对应key的保存viewModel

if (modelClass.isInstance(viewModel)) { //检查一下这个viewModel是不是已经实例化,不是null//noinspection unchecked

return (T) viewModel; //如果已经实例化,不等于null就直接返回

} else{//noinspection StatementWithEmptyBody

if (viewModel != null) {//TODO: log a warning.

}

}//下面就用传入的Factory类来实例化你需要的ViewModel

if (mFactory instanceof KeyedFactory) { //这里检查是不是带key

viewModel =((KeyedFactory) (mFactory)).create(key, modelClass);

}else{

viewModel=(mFactory).create(modelClass);

}

mViewModelStore.put(key, viewModel);//然后存一下ViewModel//noinspection unchecked

return (T) viewModel; //返回viewModel

}

移除缓存的ViewModel

其实蛛丝马迹就在ViewModelStore里

public classViewModelStore {private final HashMap mMap = new HashMap<>();final voidput(String key, ViewModel viewModel) {

ViewModel oldViewModel=mMap.put(key, viewModel);if (oldViewModel != null) {

oldViewModel.onCleared();

}

}finalViewModel get(String key) {returnmMap.get(key);

}

Setkeys() {return new HashSet<>(mMap.keySet());

}/*** Clears internal storage and notifies ViewModels that they are no longer used.*/

public final void clear() { //这里清理了当前Activity或者Fragment的所有ViewModel,这个方法是在Activity或者Fragment在销毁的时候有调用的

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

vm.clear();

}

mMap.clear();

}

}

自己实现ViewModelProvider.Factory

对于key的使用

End

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值