一副女、前言
之前我們已經(jīng)介紹了ViewModel的意義和使用方式蛤高。我們知道,在一個Activity創(chuàng)建ViewModel對象的時候,當由于系統(tǒng)配置變化導致Activity銷毀重建的時候襟齿,ViewModel對象并不會被有任何影響姻锁,由此可知在ViewModel中存儲的數(shù)據(jù),也不會發(fā)生變化猜欺。這對于我們開發(fā)者來說是很方便的位隶。
我們知道Activity的onSaveInstanceState和onRestoreInstanceState也可以做到這一點,但是我們知道onSaveInstanceState和onRestoreInstanceState是通過把數(shù)據(jù)序列化到內(nèi)存开皿,再從內(nèi)存中反序列化出來涧黄。通常是針對一些可以序列化和反序列化的小量數(shù)據(jù),如果是大量的數(shù)據(jù)赋荆,或者沒有序列化的笋妥,則不行了。
了解了ViewModel的強大的功能之后窄潭,我們先用一張圖來描述ViewModel的生命周期的變化:
從圖中我們可以看到春宣,只有Activity真正的銷毀的時候,ViewModel才會被清除掉嫉你,對應圖中的onCleared方法月帝。
二、源碼解析
下面我們來分析ViewModel的源碼幽污。我們先看下ViewModel對象的創(chuàng)建方式:
viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
代碼很簡單嚷辅,首先調(diào)用ViewModelProviders的of方法創(chuàng)建ViewModelProvider對象。其實從類的命名上看就很容易理解距误,ViewModelProviders和ViewModelProvider只差一個s簸搞,ViewModelProviders是一個集合,ViewModelProvider是集合中的一個對象准潭,of(this)則是通過傳入當前Activitiy的實例作為key趁俊,獲取ViewModelProviders中ViewModelProvider對象。是不是這個意思呢刑然?我們繼續(xù)分析:
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull Fragment fragment) {
return of(fragment, null);
}
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull FragmentActivity activity) {
return of(activity, null);
}
@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(ViewModelStores.of(fragment), factory);
}
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull FragmentActivity activity,
@Nullable Factory factory) {
Application application = checkApplication(activity);
if (factory == null) {
factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
}
return new ViewModelProvider(ViewModelStores.of(activity), factory);
}
我們看到of方法中有四個重載的方法寺擂,她們的區(qū)別就是傳入的this是Activity還是Fragment,還有就是闰集,是否有Factory 對象沽讹。如果沒有Factory對象,則創(chuàng)建默認的Factory武鲁。然后通過以下方式返回ViewModelProvider 對象
return new ViewModelProvider(ViewModelStores.of(fragment), factory);
我們看下ViewModelProvider的構(gòu)造函數(shù):
public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {
mFactory = factory;
this.mViewModelStore = store;
}
ViewModelStore 和Factory 對象顧名思義ViewModelStore 是用來存儲ViewModel的Factory 是用來創(chuàng)建ViewModel的爽雄。通過ViewModelStores.of(fragment)創(chuàng)建獲取ViewModelStore實例,接著我們看下ViewModelStores.of(fragment)的實現(xiàn)
@NonNull
@MainThread
public static ViewModelStore of(@NonNull Fragment fragment) {
if (fragment instanceof ViewModelStoreOwner) {
return ((ViewModelStoreOwner) fragment).getViewModelStore();
}
return holderFragmentFor(fragment).getViewModelStore();
}
/**
* @hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public static HolderFragment holderFragmentFor(Fragment fragment) {
return sHolderFragmentManager.holderFragmentFor(fragment);
}
HolderFragment holderFragmentFor(Fragment parentFragment) {
FragmentManager fm = parentFragment.getChildFragmentManager();
HolderFragment holder = findHolderFragment(fm);
if (holder != null) {
return holder;
}
holder = mNotCommittedFragmentHolders.get(parentFragment);
if (holder != null) {
return holder;
}
parentFragment.getFragmentManager()
.registerFragmentLifecycleCallbacks(mParentDestroyedCallback, false);
holder = createHolderFragment(fm);
mNotCommittedFragmentHolders.put(parentFragment, holder);
return holder;
}
HolderFragment holderFragmentFor(FragmentActivity activity) {
FragmentManager fm = activity.getSupportFragmentManager();
HolderFragment holder = findHolderFragment(fm);
if (holder != null) {
return holder;
}
holder = mNotCommittedActivityHolders.get(activity);
if (holder != null) {
return holder;
}
if (!mActivityCallbacksIsAdded) {
mActivityCallbacksIsAdded = true;
activity.getApplication().registerActivityLifecycleCallbacks(mActivityCallbacks);
}
holder = createHolderFragment(fm);
mNotCommittedActivityHolders.put(activity, holder);
return holder;
}
我們看到獲取ViewModelStore實例最終調(diào)用了holderFragmentFor方法獲取HolderFragment 實例holder 沐鼠,而HolderFragment 繼承了ViewModelStoreOwner挚瘟。在holderFragmentFor方法中首先根據(jù)activity作為key叹谁,判斷holder 是否存在。如果存在里乘盖,就直接返回holder焰檩。
HolderFragment holder = findHolderFragment(fm);
if (holder != null) {
return holder;
}
holder = mNotCommittedActivityHolders.get(activity);
if (holder != null) {
return holder;
}
如果不存在則創(chuàng)建新的holder返回,并把holde存到mNotCommittedActivityHolders這個Map中订框,以Activity作為key析苫。
if (!mActivityCallbacksIsAdded) {
mActivityCallbacksIsAdded = true;
activity.getApplication().registerActivityLifecycleCallbacks(mActivityCallbacks);
}
holder = createHolderFragment(fm);
mNotCommittedActivityHolders.put(activity, holder);
return holder;
這樣一來我們可以知道,只要HolderFragment 沒有被銷毀穿扳,mNotCommittedActivityHolders這個Map就會存在衩侥,那么存放在Map中的ViewModelStoreOwner holder就存在。
return holderFragmentFor(fragment).getViewModelStore();
然后通過getViewModelStore()方法可以得到ViewModelStore對象矛物。
接著我們看下get方法
viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
@NonNull
@MainThread
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.
}
}
viewModel = mFactory.create(modelClass);
mViewModelStore.put(key, viewModel);
//noinspection unchecked
return (T) viewModel;
}
我們很容易知道茫死,首先從Map中根據(jù)key獲取ViewModel 對象
ViewModel viewModel = mViewModelStore.get(key);
如果viewModel 不為空,則返回履羞,否則創(chuàng)建一個ViewModel對象峦萎,存放在Map中。
ViewModel oldViewModel = mMap.put(key, viewModel);
并且我們知道存放ViewModel的Key和Activity或者Fragment是對應起來的忆首。所以說當Activity重建的時候爱榔,只要mViewModelStore對象還是原來的對象,那么ViewModel對象就不會變雄卷,而且我們在上面分析知道m(xù)ViewModelStore又存放到了HolderFragment中搓蚪,也是存放到了Map中蛤售,所以只要HolderFragment沒有被銷毀丁鹉,mViewModelStore就不會被銷毀。mViewModelStore沒有被銷毀悴能,ViewModel就沒有被銷毀揣钦。ViewModel沒有被銷毀,ViewModel里面的數(shù)據(jù)就沒有被銷毀漠酿。因此得出了我們的結(jié)論冯凹。在Activity銷毀重建的時候,ViewModel里的數(shù)據(jù)是不會丟失的炒嘲。
三宇姚、小結(jié)
我們對ViewModel的源碼做一個小結(jié):
1、創(chuàng)建HolderFragment夫凸,并在HolderFragment中初始化Map<Activity, HolderFragment> mNotCommittedActivityHolders 用于存放 HolderFragment holder浑劳。
2、從HolderFragment 獲取ViewModelStore mViewModelStore
3夭拌、ViewModelStore 用于存放ViewModel對象魔熏,創(chuàng)建ViewModelProvider實例衷咽,傳入ViewModelStore 對象,對ViewModelProvider中的ViewModelStore進行初始化蒜绽。
4镶骗、通過 mViewModelStore.put(key, viewModel);獲取ViewModel實例。
其實ViewModel最核心的部分就是HolderFragment 中存放了ViewModelStore 躲雅。因為Activity在銷毀重建的時候HolderFragment 并不收到影響鼎姊,所以ViewModelStore 不會丟失。從而下面的一系列得到ViewModel對象不會銷毀相赁。