我们从下面几个方面分析Android jetpack viewmodel的原理
- viewmodel涉及的类以及数据结构
- viewmodel的启动
- viewmodel的恢复
viewmodel的启动
FragmentActivity
mFragment.attachHost(null)
FragmentController
public void attachHost(Fragment parent)
mHost.mFragmentManager.attachController(mHost, mHost, parent)
FragmentManager
void attachController(FragmentHostCallback<?> host, FragmentContainer container, Fragment parent){
//get the fragmentManagerViewModel
if(parent != null){
mNonConfig = parent.mFragmentManager.getChildNonConfig(parent);
}else if(host instanceof ViewModelStoreOwner){
ViewModelStore viewModelStore = ((ViewModelStoreOwner)host).getViewModelStore();
mNonConfig = FragmentManagerViewModel.getInstance(viewModelStore)
}else{
mNonConfig = new FragmentManagerViewModel(false)
}
}
viewmodel的恢复
Activity
ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance, String reason) {
...
if (getNonConfigInstance) {
try {
r.lastNonConfigurationInstances
= r.activity.retainNonConfigurationInstances();
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to retain activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
}
...
}
//把mViewModelStore保存在new 出来的NonConfigurationInstances实例中
ComponentActivity
public final Object onRetainNonConfigurationInstance() {
// Maintain backward compatibility.
Object custom = onRetainCustomNonConfigurationInstance();
ViewModelStore viewModelStore = mViewModelStore;
if (viewModelStore == null) {
// No one called getViewModelStore(), so see if there was an existing
// ViewModelStore from our last NonConfigurationInstance
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
viewModelStore = nc.viewModelStore;
}
}
if (viewModelStore == null && custom == null) {
return null;
}
NonConfigurationInstances nci = new NonConfigurationInstances();
nci.custom = custom;
nci.viewModelStore = viewModelStore;
return nci;
}