系统源码参考自 Android API 30 Platform,以及 androidx.lifecycle:lifecycle-viewmodel:2.2.0
在文章开始之前,有如下几点疑惑,先记录下来:
ViewModel#onCleared()
的调用时机 ?- ViewModel 与
onSaveInstanceState()
有联系吗?或者有什么区别吗? - ViewModel 是否涉及序列化与反序列化?
- 一个 Activity 中是否支持多个 ViewModel ?
ViewModelProvider#get()
的使用时机。
1. 与 ViewModel
相关的类
1.1 ViewModelStore
和 ViewModelStoreOwner
ViewModel
实现的关键就是 ViewModelStore
,其内部有一个 HashMap<String, ViewModel>
用于存储多个 ViewModel
实例,即本质上就是一个用来维护多个 ViewModel
实例的 map
容器。
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 (oldViewModel != null) {
oldViewModel.onCleared();
}
}
final ViewModel get(String key) {
return mMap.get(key);
}
...
}
另外,还涉及到 ViewModelStoreOwner
接口。
public interface ViewModelStoreOwner {
@NonNull
ViewModelStore getViewModelStore();
}
1.2 androidx.activity.ComponentActivity
androidx.activity.ComponentActivity
(源码基于 androidx.activity:activity:1.1.0
),就是我们常用的 androidx.appcompat.app.AppCompatActivity
的父类。
androidx.activity.ComponentActivity
继承自 androidx.core.app.ComponentActivity
,且实现了 ViewModelStoreOwner
接口,同时内部维护了对应的成员变量 mViewModelStore
(ViewModelStore
类型的)。
// androidx.activity.ComponentActivity
@NonNull
@Override
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) {
// NonConfigurationInstances 为 ComponentActivity 中的内部静态类
NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
// Restore the ViewModelStore from NonConfigurationInstances
mViewModelStore = nc.viewModelStore;
}
// 如果前面都没有获取到 ViewModelStore 实例,则这里直接实例化一个新的
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
}
return mViewModelStore;
}
static final class NonConfigurationInstances {
Object custom;
ViewModelStore viewModelStore;
}
而 getLastNonConfigurationInstance()
是 android.app.Activity
的成员方法。
// android.app.Activity
/**
* Retrieve the non-configuration instance data that was previously
* returned by {@link #onRetainNonConfigurationInstance()}. This will
* be available from the initial {@link #onCreate} and
* {@link #onStart} calls to the new instance, allowing you to extract
* any useful dynamic state from the previous instance.
*
* <p>Note that the data you retrieve here should <em>only</em> be used
* as an optimization for handling configuration changes. You should always
* be able to handle getting a null pointer back, and an activity must
* still be able to restore itself to its previous state (through the
* normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this
* function returns null.
*
* <p><strong>Note:</strong> For most cases you should use the {@link Fragment} API
* {@link Fragment#setRetainInstance(boolean)} instead; this is also
* available on older platforms through the Android support libraries.
*
* @return the object previously returned by {@link #onRetainNonConfigurationInstance()}
*/
@Nullable
public Object getLastNonConfigurationInstance() {
// mLastNonConfigurationInstances 则是在 Activity 中定义的内部静态类 ComponentActivity.NonConfigurationInstances 类型
return mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.activity : null;
}
static final class NonConfigurationInstances {
Object activity;
HashMap<String, Object> children;
FragmentManagerNonConfig fragments;
ArrayMap<String, LoaderManager> loaders;
VoiceInteractor voiceInteractor;
}
在 android.app.Activity
内部维护着成员变量 mLastNonConfigurationInstances
,其是在 Activity#attach()
中被赋值的,其中 lastNonConfigura