ViewModel源码解析
源码版本:
- ViewModel:2.4.0
- Android:31
- androidx.activity:activity:1.4.0
- androidx.fragment:fragment:1.4.0
需会使用:
Lifecycle
导航:
使用
声明ViewModel
class MyViewModel : ViewModel() {
override fun onCleared() {
super.onCleared()
}
}
获取ViewModel
class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// 获取ViewModel
val model = ViewModelProvider(this).get(MyViewModel::class.java)
// observe
model.getUsers().observe(this, Observer<List<User>>{ users ->
// update UI
})
}
}
ViewModel生命周期
enter image description here源码
声明ViewModel
ViewModel类
public abstract class ViewModel {
// 标签集合
@Nullable
private final Map<String, Object> mBagOfTags = new HashMap<>();
// 标记是否是已清除
private volatile boolean mCleared = false;
// 当ViewModel被清除时调用
protected void onCleared() {
}
@MainThread
final void clear() {
mCleared = true;
if (mBagOfTags != null) {
synchronized (mBagOfTags) {
for (Object value : mBagOfTags.values()) {
// see comment for the similar call in setTagIfAbsent
closeWithRuntimeException(value);
}
}
}
onCleared();
}
// 添加数据key、value,如果key的值已经存在,则返回已存在的值,否则添加新的值。
// 并判断如果ViewModel是已被清除的,则返回的值如果是Closeable,就会调用close方法释放。即ViewModel已经被清除,再添加新的,则也会释放。
@SuppressWarnings("unchecked")
<T> T setTagIfAbsent(String key, T newValue) {
T previous;
synchronized (mBagOfTags) {
previous = (T) mBagOfTags.get(key);
if (previous == null) {
mBagOfTags.put(key, newValue);
}
}
T result = previous == null ? newValue : previous;
if (mCleared) {
closeWithRuntimeException(result);
}
return result;
}
// 获取被添加的数据
<T> T getTag(String key) {
if (mBagOfTags == null) {
return null;
}
synchronized (mBagOfTags) {
return (T) mBagOfTags.get(key);
}
}
private static void closeWithRuntimeException(Object obj) {
if (obj instanceof Closeable) {
// 是Closeable子类,则调用close关闭。
try {
((Closeable) obj).close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
ViewModel
被清除的时候,会清空Tag
并调用onCleared
方法通知ViewModel
被清除。
获取ViewModel
使用
class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// 获取ViewModel
val model = ViewModelProvider(this).get(MyViewModel::class.java)
// observe
model.getUsers().observe(this, Observer<List<User>>{ users ->
// update UI
})
}
}
获取ViewModel
,首先需要创建ViewModelProvider
,然后再调用其get
方法获取,我们先来看一下ViewModelProvider
对象是如果创建的,然后再看get
方法是如果获取的。
ViewModelProvider构造方法
ViewModelProvider构造方法
public open class ViewModelProvider(
private val store: ViewModelStore,
private val factory: Factory
) {
public constructor(
owner: ViewModelStoreOwner
) : this(owner.viewModelStore, defaultFactory(owner))
public constructor(owner: ViewModelStoreOwner, factory: Factory) : this(
owner.viewModelStore,
factory
)
}
ViewModelProvider
为ViewModel
提供者,创建它需要ViewModelStore
和ViewModelProvider.Factory
,而ViewModelStore
又可以从ViewModelStoreOwner
中获取,我们分别来看下这几个类。
ViewModelStore
ViewModelStore类
public class ViewModelStore {
// ViewModel集合
private final HashMap<String, ViewModel> mMap = new HashMap<>();
TestViewModel
// 保存ViewModel,如果key已经存在,则值进行覆盖,之前的ViewModel则调用onCleared清空逻辑。
final void put(String key, ViewModel viewModel) {
ViewModel oldViewModel = mMap.put(key, viewModel);
if (oldViewModel != null) {
oldViewModel.onCleared();
}
}
// 获取ViewModel
final ViewModel get(String key) {
return mMap.get(key);
}
// 获取所有的key
Set<String> keys() {
return new HashSet<>(mMap.keySet());
}
// 清除内部存储并通知ViewModels它们不再使用。
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.clear();
}
mMap.clear();
}
}
ViewModelProvider
为ViewModel
商店,它是用来存储或获取ViewModel
的,是使用HashMap
来实现的。其clear
方法会清除内部存储并通知ViewModels
它们不再使用。
ViewModelStoreOwner
ViewModelStoreOwner类
public interface ViewModelStoreOwner {
@NonNull
ViewModelStore getViewModelStore();
}
ViewModelStoreOwner
为ViewModelStore
的持有者,通过它的子类可以获取到ViewModelStore
。androidx
的Activity
和Fragment
都已经实现了ViewModelStoreOwner
,我们分别看一下具体实现。
Activity
androidx.activity.ComponentActivity类
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
ContextAware,
LifecycleOwner,
ViewModelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner,
ActivityResultRegistryOwner,
ActivityResultCaller {
private ViewModelStore mViewModelStore;
@NonNull
@Override
public ViewModelStore getViewModelStore() {
if (getApplication() == null) {
// 不能在onCreate调用之前获取ViewModel
throw new IllegalStateException("Your activity is not yet attached to the "
+ "Application instance. You can't request ViewModel before onCreate call.");
}
// 确保ViewModelStore
ensureViewModelStore();
// 返回ViewModelStore
return mViewModelStore;
}
@SuppressWarnings("WeakerAccess") /* synthetic access */
void ensureViewModelStore() {
if (mViewModelStore == null) {
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
// 从 NonConfigurationInstances 中恢复ViewModelStore
mViewModelStore = nc.viewModelStore;
}
if (mViewModelStore == null) {
// mViewModelStore为空,则创建。
mViewModelStore = new ViewModelStore();
}
}
}
}
androidx
Activity
获取ViewModelStore
,先从 NonConfigurationInstances
中恢复ViewModelStore
(确保Activity
重建后还能获取到之前的ViewModelStore
,具体分析看下面ViewModel是如何保持不变的?
),如果还是没有,则进行创建。
说明:
androidx
Activity
不能在onCreate
调用之前获取ViewModel
。
Fragment
androidx.fragment.app.Fragment类
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
ViewModelStoreOwner, HasDefaultViewModelProviderFactory, SavedStateRegistryOwner,
ActivityResultCaller {
@NonNull
@Override
public ViewModelStore getViewModelStore() {
if (mFragmentManager == null) {
// 不能从detached的Fragment访问ViewModels
throw new IllegalStateException("Can't access ViewModels from detached fragment");
}
if (getMinimumMaxLifecycleState() == Lifecycle.State.INITIALIZED.ordinal()) {
// 当使用setMaxLifecycle(INITIALIZED)时,不支持在Fragment到达onCreate()之前调用getViewModelStore()
throw new IllegalStateException("Calling getViewModelStore() before a Fragment "
+ "reaches onCreate() when using setMaxLifecycle(INITIALIZED) is not "
+ "supported");
}
return mFragmentManager.getViewModelStore(this);
}
}
FragmentManager --> getViewModelStore方法
@NonNull
ViewModelStore getViewModelStore(@NonNull Fragment f) {
return mNonConfig.getViewModelStore(f);
}
FragmentManagerViewModel --> getViewModelStore方法
@NonNull
ViewModelStore getViewModelStore(@NonNull Fragment f) {
ViewModelStore viewModelStore = mViewModelStores.get(f.mWho);
if (viewModelStore == null) {
viewModelStore = new ViewModelStore();
mViewModelStores.put(f.mWho, viewModelStore);
}
return viewModelStore;
}
androidx
Fragment
获取ViewModelStore
,先获取到 FragmentManagerViewModel
(确保Fragment
重建后还能获取到之前的ViewModelStore
,具体分析看下面ViewModel是如何保持不变的?
),然后再从其mViewModelStores
中获取,如果没有,则进行创建。
说明:
androidx
Fragment
不能在onDetach
调用之后获取ViewModel
。
ViewModelProvider.Factory
ViewModelProvider.Factory类
public interface Factory {
// 创建给定ViewModel Class的新实例。
@NonNull
<T extends ViewModel> T create(@NonNull Class<T> modelClass);
}
ViewModelProvider.Factory
为ViewModel
的创建工厂,此Factory
通过ViewModel
类的class
,创建ViewModel
实例。我们分别来看一下它的子类KeyedFactory
、NewInstanceFactory
、AndroidViewModelFactory
。
ViewModelProvider.KeyedFactory
ViewModelProvider.KeyedFactory类
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public abstract class KeyedFactory : OnRequeryFactory(), Factory {
public abstract fun <T : ViewModel> create(
key: String,
modelClass: Class<T>
): T
override fun <T : ViewModel> create(modelClass: Class<T>): T {
throw UnsupportedOperationException(
"create(String, Class<?>) must be called on implementations of KeyedFactory"
)
}
}
KeyedFactory
为Factory
的抽象子类,重写了create(Class<?>)
方法,并且KeyedFactory
子类必须重写create( Class<?>)
方法并应该调用其create(String, Class<?>)
方法。
ViewModelProvider.NewInstanceFactory
ViewModelProvider.NewInstanceFactory类
public open class NewInstanceFactory : Factory {
@Suppress("DocumentExceptions")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return try {
// 通过反射获取实例
modelClass.newInstance()
} catch (e: InstantiationException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
} catch (e: IllegalAccessException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
}
}
public companion object {
private var sInstance: NewInstanceFactory? = null
// 单例 NewInstanceFactory
@JvmStatic
public val instance: NewInstanceFactory
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
get() {
if (sInstance == null) {
sInstance = NewInstanceFactory()
}
return sInstance!!
}
}
}
NewInstanceFactory
为Factory
的子类,实现了create(Class<?>)
方法,通过ViewModel
类的class
,无参反射创建ViewModel
实例。
说明:
- 使用
NewInstanceFactory
创建,此ViewModel
必须有无参的且不是私有的构造方法。
- 可以处理如下
ViewModel
:
class MyViewModel : ViewModel()
NewInstanceFactory.instance
为全局单例NewInstanceFactory
,防止了每次创建工厂,优化了性能。
ViewModelProvider.AndroidViewModelFactory
ViewModelProvider.AndroidViewModelFactory类
public open class AndroidViewModelFactory(
private val application: Application
) : NewInstanceFactory() {
@Suppress("DocumentExceptions")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return if (AndroidViewModel::class.java.isAssignableFrom(modelClass)) {
try {
// 此ViewModel为AndroidViewModel的子类,则传入Application并创建。
modelClass.getConstructor(Application::class.java).newInstance(application)
} catch (e: NoSuchMethodException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
} catch (e: IllegalAccessException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
} catch (e: InstantiationException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
} catch (e: InvocationTargetException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
}
} else super.create(modelClass) // 否则,则执行父类的反射创建。
}
public companion object {
// 获取默认工厂,如果owner有默认工厂则用owner的,否则用NewInstanceFactory工厂(反射创建)。
internal fun defaultFactory(owner: ViewModelStoreOwner): Factory =
if (owner is HasDefaultViewModelProviderFactory)
owner.defaultViewModelProviderFactory else instance
// 获取的默认Key
internal const val DEFAULT_KEY = "androidx.lifecycle.ViewModelProvider.DefaultKey"
private var sInstance: AndroidViewModelFactory? = null
// 单例 AndroidViewModelFactory
@JvmStatic
public fun getInstance(application: Application): AndroidViewModelFactory {
if (sInstance == null) {
sInstance = AndroidViewModelFactory(application)
}
return sInstance!!
}
}
}
AndroidViewModelFactory
为NewInstanceFactory
的子类,重写了create(Class<?>)
方法,通过ViewModel
类的class
判断,如果此ViewModel
为AndroidViewModel
的子类,则传入Application
并反射创建,否则走父类逻辑无参反射创建ViewModel
实例。
说明:
- 使用
AndroidViewModelFactory
创建,如果此ViewModel
是AndroidViewModel
子类,必须有一参的且是Application
且不是私有的构造方法(不能无参);否则必须有无参的且不是私有的构造方法(不能有参)。
- 可以处理如下
ViewModel
:
class MyViewModel : ViewModel()
class MyViewModel(application: Application) : AndroidViewModel(application)
AndroidViewModelFactory.getInstance
为全局单例AndroidViewModelFactory
,防止了每次创建工厂,优化了性能。
defaultFactory
方法为获取默认工厂,如果ViewModelStoreOwner
子类也实现了HasDefaultViewModelProviderFactory
,则用其提供的工厂,否则用NewInstanceFactory
工厂(创建无参ViewModel
)。
HasDefaultViewModelProviderFactory
HasDefaultViewModelProviderFactory类
public interface HasDefaultViewModelProviderFactory {
// 获取默认Factory
@NonNull
ViewModelProvider.Factory getDefaultViewModelProviderFactory();
}
HasDefaultViewModelProviderFactory
为标记可以获取到默认Factory
。androidx
的Activity
和Fragment
都已经实现了HasDefaultViewModelProviderFactory
,我们来分别看一下它们的具体实现。
Activity
androidx.activity.ComponentActivity类
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
ContextAware,
LifecycleOwner,
ViewModelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner,
ActivityResultRegistryOwner,
ActivityResultCaller {
private ViewModelProvider.Factory mDefaultFactory;
@NonNull
@Override
public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
if (getApplication() == null) {
// 不能在onCreate调用之前获取ViewModel
throw new IllegalStateException("Your activity is not yet attached to the "
+ "Application instance. You can't request ViewModel before onCreate call.");
}
if (mDefaultFactory == null) {
// 默认工厂为空,则进行创建SavedStateViewModelFactory,会把Application、当前页面传入的参数,传入到构造方法中。
mDefaultFactory = new SavedStateViewModelFactory(
getApplication(),
this,
getIntent() != null ? getIntent().getExtras() : null);
}
return mDefaultFactory;
}
}
Fragment
androidx.fragment.app.Fragment类
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
ViewModelStoreOwner, HasDefaultViewModelProviderFactory, SavedStateRegistryOwner,
ActivityResultCaller {
ViewModelProvider.Factory mDefaultFactory;
@NonNull
@Override
public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
if (mFragmentManager == null) {
// 不能从detached的Fragment访问ViewModels
throw new IllegalStateException("Can't access ViewModels from detached fragment");
}
if (mDefaultFactory == null) {
// 默认工厂为空,则进行创建SavedStateViewModelFactory,会把Application、当前页面传入的参数,传入到构造方法中。
Application application = null;
Context appContext = requireContext().getApplicationContext();
while (appContext instanceof ContextWrapper) {
if (appContext instanceof Application) {
application = (Application) appContext;
break;
}
appContext = ((ContextWrapper) appContext).getBaseContext();
}
if (application == null && FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(FragmentManager.TAG, "Could not find Application instance from "
+ "Context " + requireContext().getApplicationContext() + ", you will "
+ "not be able to use AndroidViewModel with the default "
+ "ViewModelProvider.Factory");
}
// 创建SavedStateViewModelFactory
mDefaultFactory = new SavedStateViewModelFactory(
application,
this,
getArguments());
}
return mDefaultFactory;
}
}
androidx
的Activity
和Fragment
的实现相同,都是创建SavedStateViewModelFactory
并会把Application
、当前页面传入的参数,传入到构造方法中,我们来看一下SavedStateViewModelFactory
。
SavedStateViewModelFactory
SavedStateViewModelFactory类
public final class SavedStateViewModelFactory extends ViewModelProvider.KeyedFactory {
private final Application mApplication;
private final ViewModelProvider.Factory mFactory;
private final Bundle mDefaultArgs;
private final Lifecycle mLifecycle;
private final SavedStateRegistry mSavedStateRegistry;
// 构造方法,未传默认参数
public SavedStateViewModelFactory(@Nullable Application application,
@NonNull SavedStateRegistryOwner owner) {
this(application, owner, null);
}
// 构造方法,传了默认参数
@SuppressLint("LambdaLast")
public SavedStateViewModelFactory(@Nullable Application application,
@NonNull SavedStateRegistryOwner owner,
@Nullable Bundle defaultArgs) {
mSavedStateRegistry = owner.getSavedStateRegistry();
mLifecycle = owner.getLifecycle();
mDefaultArgs = defaultArgs;
mApplication = application;
mFactory = application != null
? ViewModelProvider.AndroidViewModelFactory.getInstance(application)
: ViewModelProvider.NewInstanceFactory.getInstance();
}
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull String key, @NonNull Class<T> modelClass) {
// 是否是AndroidViewModel子类
boolean isAndroidViewModel = AndroidViewModel.class.isAssignableFrom(modelClass);
Constructor<T> constructor;
if (isAndroidViewModel && mApplication != null) {
// 是AndroidViewModel子类,获取(Application, SavedStateHandle)签名的构造方法
constructor = findMatchingConstructor(modelClass, ANDROID_VIEWMODEL_SIGNATURE);
} else {
// 不是AndroidViewModel子类,获取(SavedStateHandle)签名的构造方法
constructor = findMatchingConstructor(modelClass, VIEWMODEL_SIGNATURE);
}
if (constructor == null) {
// 没有获取到,则说明是没用SavedStateHandle的构造方法,则直接用mFactory处理。
return mFactory.create(modelClass);
}
// 以下为需要SavedStateHandle
SavedStateHandleController controller = SavedStateHandleController.create(
mSavedStateRegistry, mLifecycle, key, mDefaultArgs);
try {
T viewmodel;
if (isAndroidViewModel && mApplication != null) {
// 反射创建(Application, SavedStateHandle)签名的构造方法,并传入SavedStateHandle。
viewmodel = constructor.newInstance(mApplication, controller.getHandle());
} else {
// 反射创建(SavedStateHandle)签名的构造方法,并传入SavedStateHandle。
viewmodel = constructor.newInstance(controller.getHandle());
}
viewmodel.setTagIfAbsent(TAG_SAVED_STATE_HANDLE_CONTROLLER, controller);
// 返回ViewModel
return viewmodel;
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to access " + modelClass, e);
} catch (InstantiationException e) {
throw new RuntimeException("A " + modelClass + " cannot be instantiated.", e);
} catch (InvocationTargetException e) {
throw new RuntimeException("An exception happened in constructor of "
+ modelClass, e.getCause());
}
}
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
String canonicalName = modelClass.getCanonicalName();
if (canonicalName == null) {
throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
}
// 使用类名作为key,创建ViewModemLastNonConfigurationInstancesl。
return create(canonicalName, modelClass);
}
// (Application, SavedStateHandle)签名
private static final Class<?>[] ANDROID_VIEWMODEL_SIGNATURE = new Class[]{Application.class,
SavedStateHandle.class};
// (SavedStateHandle)签名
private static final Class<?>[] VIEWMODEL_SIGNATURE = new Class[]{SavedStateHandle.class};
// 找到对应签名的构造方法,没有返回null。
@SuppressWarnings("unchecked")
private static <T> Constructor<T> findMatchingConstructor(Class<T> modelClass,
Class<?>[] signature) {
for (Constructor<?> constructor : modelClass.getConstructors()) {
Class<?>[] parameterTypes = constructor.getParameterTypes();
if (Arrays.equals(signature, parameterTypes)) {
return (Constructor<T>) constructor;
}
}
return null;
}
/**
* @hide
*/
@Override
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public void onRequery(@NonNull ViewModel viewModel) {
attachHandleIfNeeded(viewModel, mSavedStateRegistry, mLifecycle);
}
}
androidx
的Activity
和Fragment
创建默认工厂的代码流程:
androidx
的Activity
和Fragment
创建SavedStateViewModelFactory
时,都传入了Application
,所以其工厂mFactory
为AndroidViewModelFactory
。create(String,Class<*>)
方法,如果ViewModel
构造方法里面没有用SavedStateHandle
,则直接使用工厂mFactory
(为AndroidViewModelFactory
)进行创建。
说明:
- 使用
SavedStateViewModelFactory
创建,如果此ViewModel
构造方法里面没有用SavedStateHandle
,则直接使用AndroidViewModelFactory
创建;如果使用了,则反射创建(Application, SavedStateHandle)
或(SavedStateHandle)
签名的构造方法。
- 可以处理如下
ViewModel
:
class MyViewModel : ViewModel()
class MyViewModel(application: Application) : AndroidViewModel(application)
class MyViewModel(val handle: SavedStateHandle) : ViewModel()
class MyViewModel(application: Application, val handle: SavedStateHandle) : AndroidViewModel(application)
- 由于
SavedStateHandle
的创建,传入了当前页面传入的参数,所以通过SavedStateHandle
也能获取到当前页面传入的参数。- 使用
SavedStateHandle
相关的,将在Jetpact-保存状态讲解。
说完了ViewModelProvider
对象的创建,我们再来看看其get()
方法是如果获取ViewModel
的。
ViewModelProvider.get方法
ViewModelProvider--> get方法
@MainThread
public open operator fun <T : ViewModel> get(modelClass: Class<T>): T {
// 获取类名
val canonicalName = modelClass.canonicalName
?: throw IllegalArgumentException("Local and anonymous classes can not be ViewModels")
// 使用默认名+类名作为key,获取ViewModel。
return get("$DEFAULT_KEY:$canonicalName", modelClass)
}
@Suppress("UNCHECKED_CAST")
@MainThread
public open operator fun <T : ViewModel> get(key: String, modelClass: Class<T>): T {
// 从ViewModelStore中获取ViewModel
var viewModel = store[key]
if (modelClass.isInstance(viewModel)) {
// viewModel不为空,并且是目标类,直接返回。
(factory as? OnRequeryFactory)?.onRequery(viewModel)
return viewModel as T
} else {
@Suppress("ControlFlowWithEmptyBody")
if (viewModel != null) {
// TODO: log a warning.
}
}
// 没有找到ViewModel,则直接创建,并存入到ViewModelStore中。
viewModel = if (factory is KeyedFactory) {
// 是KeyedFactory的子类直接调用create(key, modelClass)方法。
factory.create(key, modelClass)
} else {
factory.create(modelClass)
}
// 存入到ViewModelStore中
store.put(key, viewModel)
return viewModel
}
ViewModelProvider.get
代码流程:
get(Class<*>)
方法,使用默认名+类名作为key
,调用get(String, Class<*>)
方法,获取ViewModel
。get(String, Class<*>)
方法,先从ViewModelStore
中获取ViewModel
,如果有并且是目标类,则直接返回,否则使用Factory
直接创建,并存入到ViewModelStore
中,以便后续获取。
总结
以在androidx
的Activity
内获取无参构造方法ViewModel
为例,讲解代码流程。
声明ViewModel
class MyViewModel : ViewModel() {
override fun onCleared() {
super.onCleared()
}
}
获取ViewModel
class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// 获取ViewModel
val model = ViewModelProvider(this).get(MyViewModel::class.java)
}
}
示例代码流程:
- 创建
ViewModelProvider
,传入的是ComponentActivity
,它的ViewModelStore
为ComponentActivity
提供的ViewModelStore
,它的Factory
为ComponentActivity
提供的默认工厂SavedStateViewModelFactory
。get()
方法,先从ViewModelStore
中获取ViewModel
,如果有并且是目标类,则直接返回,否则使用Factory
(SavedStateViewModelFactory
)直接创建,并存入到ViewModelStore
中,以便后续获取。SavedStateViewModelFactory
的create()
方法,会直接调用AndroidViewModelFactory
的create()
方法。(因为获取的MyViewModel
未使用SavedStateHandle
,所以会直接调用mFactory
的创建。又因为创建SavedStateViewModelFactory
时传入了Application
,所以mFactory
为AndroidViewModelFactory
)AndroidViewModelFactory
的create()
方法,会直接使用反射创建无参构造方法。(因为获取的MyViewModel
未继承AndroidViewModel
,所以会走父类NewInstanceFactory
的逻辑创建)
ViewModel生命周期
ViewModel
生命周期为什么会比Activity
、Fragment
的生命周期长,它是如何保持不变的,以及它是如何被清除的,我们来分别分析以下。
ViewModel是如何保持不变的?
Activity
和Fragment
在配置变更(如:屏幕旋转)的情况会销毁并重新创建,但是再次获取的ViewModel
实例不变。反向分析其原因,要想要ViewModel
实例不变,则需要保持ViewModelStore
不变。我们分别看一下androidx
的Activity
和Fragment
的getViewModelStore()
方法。
Activity
ComponentActivity--> getViewModelStore方法
@NonNull
@Override
public ViewModelStore getViewModelStore() {
if (getApplication() == null) {
// 不能在onCreate调用之前获取ViewModel
throw new IllegalStateException("Your activity is not yet attached to the "
+ "Application instance. You can't request ViewModel before onCreate call.");
}
// 确保ViewModelStore
ensureViewModelStore();
// 返回ViewModelStore
return mViewModelStore;
}
@SuppressWarnings("WeakerAccess") /* synthetic access */
void ensureViewModelStore() {
if (mViewModelStore == null) {
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
// 从 NonConfigurationInstances 中恢复ViewModelStore
mViewModelStore = nc.viewModelStore;
}
if (mViewModelStore == null) {
// mViewModelStore为空,则创建。
mViewModelStore = new ViewModelStore();
}
}
}
获取ViewModelStore
,我们先从NonConfigurationInstances
中获取,其内部包含了一个ViewModelStore
成员变量,我们先来分析一下NonConfigurationInstances.viewModelStore
是如何被赋值的,然后再来分析又是如何获取到它的。
说明:
- 为什么
ComponentActivity
的mViewModelStore
属性,在配置变更之前存入值,而在配置变更之后为空?
- 因为
Activity
在配置变更之后,重新创建的Activity
,Activity
对象为新的,所以其mViewModelStore
属性为初始状态:空。
ComponentActivity.NonConfigurationInstances类
static final class NonConfigurationInstances {
Object custom;
ViewModelStore viewModelStore;
}
通过查找引用,NonConfigurationInstances.viewModelStore
是在ComponentActivity
的onRetainNonConfigurationInstance()
方法里完成赋值的。
ComponentActivity--> onRetainNonConfigurationInstance方法
public final Object onRetainNonConfigurationInstance() {
// Maintain backward compatibility.
Object custom = onRetainCustomNonConfigurationInstance();
ViewModelStore viewModelStore = mViewModelStore;
if (viewModelStore == null) {
// viewModelStore为空,则说明此时没有调用过getViewModelStore(),则通过getLastNonConfigurationInstance()从重建之前的获取。
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
viewModelStore = nc.viewModelStore;
}
}
if (viewModelStore == null && custom == null) {
return null;
}
NonConfigurationInstances nci = new NonConfigurationInstances();
nci.custom = custom;
// 记录当前viewModelStore,完成赋值操作。
nci.viewModelStore = viewModelStore;
return nci;
}
此方法,创建ComponentActivity.NonConfigurationInstances
对象,记录当前viewModelStore
,并返回此对象。
说明:
- 重写了父类
Activity
的onRetainNonConfigurationInstance()
方法,使其创建的ComponentActivity.NonConfigurationInstances
对象,在配置变更之后不受影响。ComponentActivity.NonConfigurationInstances.viewModelStore
属性,保存了在配置变更之前维护的ViewModelStore
。
通过查找引用,ComponentActivity.onRetainNonConfigurationInstance()
方法是在Activity
的retainNonConfigurationInstances()
方法里调用的。
Activity--> retainNonConfigurationInstances方法
NonConfigurationInstances retainNonConfigurationInstances() {
// 获取到当前activity要保存的数据
Object activity = onRetainNonConfigurationInstance();
HashMap<String, Object> children = onRetainNonConfigurationChildInstances();
FragmentManagerNonConfig fragments = mFragments.retainNestedNonConfig();
// We're already stopped but we've been asked to retain.
// Our fragments are taken care of but we need to mark the loaders for retention.
// In order to do this correctly we need to restart the loaders first before
// handing them off to the next activity.
mFragments.doLoaderStart();
mFragments.doLoaderStop(true);
ArrayMap<String, LoaderManager> loaders = mFragments.retainLoaderNonConfig();
if (activity == null && children == null && fragments == null && loaders == null
&& mVoiceInteractor == null) {
return null;
NonConfigurationInstances nci = new NonConfigurationInstances();
// 记录当前activity数据,完成赋值操作。
nci.activity = activity;
nci.children = children;
nci.fragments = fragments;
nci.loaders = loaders;
if (mVoiceInteractor != null) {
mVoiceInteractor.retainInstance();
nci.voiceInteractor = mVoiceInteractor;
}
return nci;
}
此方法,创建Activity.NonConfigurationInstances
对象,记录其activity
要保存数据(即ComponentActivity.NonConfigurationInstances
对象),并返回此对象。
说明:
Activity
的retainNonConfigurationInstances()
方法,使其创建的Activity.NonConfigurationInstances
对象,在配置变更之后不受影响。Activity.NonConfigurationInstances.activity
属性,保存了ComponentActivity.NonConfigurationInstances
对象。
通过全局搜索,Activity.retainNonConfigurationInstances()
方法是在ActivityThread
的performDestroyActivity()
方法里调用的。
ActivityThread--> performDestroyActivity方法
void performDestroyActivity(ActivityClientRecord r, boolean finishing,
int configChanges, boolean getNonConfigInstance, String reason) {
...
if (getNonConfigInstance) {
try {
// 从ActivityClientRecord的Activity中获取Activity.NonConfigurationInstances对象,
// 然后保存到它的lastNonConfigurationInstances中,完成保存操作。
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);
}
}
}
...
// 回调Activity的onDestroy方法
mInstrumentation.callActivityOnDestroy(r.activity);
...
}
在Activity
执行销毁的时候,会先将不会因配置变更而改变的数据(即Activity.NonConfigurationInstances
)保存到ActivityClientRecord
的lastNonConfigurationInstances
属性中。
说明:
ActivityThread
:它管理应用程序进程中主线程的执行、调度和执行activity
、广播以及activity manager
请求的其它操作。ActivityClientRecord
:Activity
客户端记录,用于真实的Activity
实例的簿记。ActivityClientRecord.lastNonConfigurationInstances.activity.viewModelStore
属性,保存了在配置变更之前维护的ViewModelStore
。
接下来,我们来看一下是如果获取到保存了在配置变更之前维护的ViewModelStore
的,我们先来看一下Activity.getLastNonConfigurationInstance()
方法。
Activity--> getLastNonConfigurationInstance方法
@Nullable
public Object getLastNonConfigurationInstance() {
return mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.activity : null;
}
mLastNonConfigurationInstances
为Activity.NonConfigurationInstances
,getLastNonConfigurationInstance()
结果返回的是其activity
属性,即ComponentActivity.NonConfigurationInstances
对象。
我们再来看一下,mLastNonConfigurationInstances
是在哪里进行赋值的。通过查找,mLastNonConfigurationInstances
是在Activity
的attach()
里赋值的。
Activity--> attach方法
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken,
IBinder shareableActivityToken) {
...
// 完成赋值操作
mLastNonConfigurationInstances = lastNonConfigurationInstances;
...
}
通过全局搜索,Activity.retainNonConfigurationInstances()
方法是在ActivityThread
的performDestroyActivity()
方法里调用的。
ActivityThread--> performLaunchActivity方法
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
// 调用attach,传入ActivityClientRecord的lastNonConfigurationInstances。
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken, r.shareableActivityToken);
...
return activity;
}
在Activity
执行启动的时候,会调用其attach()
方法,传入ActivityClientRecord.lastNonConfigurationInstances
保存的Activity.NonConfigurationInstances
对象。
说明:
- 为什么
ActivityThread
的performLaunchActivity()
、performDestroyActivity()
方法里面ActivityClientRecord
是同一个?
- 因为
ActivityClientRecord
保存在了ActivityThread.mActivities
属性中,其为ActivityClientRecord
的Map
集合,ActivityClientRecord
在startActivityNow()
方法内创建,并调用performLaunchActivity()
方法,在其内部保存了创建的ActivityClientRecord
对象,所以之后也能从Map
中获取到之前存入的ActivityClientRecord
,所以performLaunchActivity()
、performDestroyActivity()
方法里面ActivityClientRecord
是同一个。
代码流程:
- 在
ActivityThread.performDestroyActivity()
方法,ActivityClientRecord.lastNonConfigurationInstances
保存了Activity.retainNonConfigurationInstances()
方法返回的Activity.NonConfigurationInstances
对象。- 其中的
Activity.NonConfigurationInstances.activity
属性,保存了ComponentActivity.onRetainNonConfigurationInstance()
方法返回的ComponentActivity.NonConfigurationInstances
对象。- 其中的
ComponentActivity.NonConfigurationInstances.viewModelStore
属性,保存了在配置变更之前维护的ViewModelStore
。- 在
ActivityThread.performLaunchActivity()
方法,调用Activity.attach()
方法,传入了保存在ActivityClientRecord.lastNonConfigurationInstances
的Activity.NonConfigurationInstances
对象。Activity.attach()
方法,保存了传入的Activity.NonConfigurationInstances
对象。- 通过调用
Activity.getLastNonConfigurationInstance()
方法,即可拿到Activity.NonConfigurationInstances.activity
属性保存的ComponentActivity.NonConfigurationInstances
对象。- 最后获取
ComponentActivity.NonConfigurationInstances.viewModelStore
属性的值,即可拿到ComponentActivity
的ViewModelStore
对象。
总结:
- 在
Activity
销毁的时候,ActivityClientRecord.lastNonConfigurationInstances.activity.viewModelStore
属性,保存了在配置变更之前维护的ViewModelStore
。- 在
Activity
启动的时候,ActivityClientRecord.lastNonConfigurationInstances
的值在Activity.attach()
的时候被存入到了Activity
中,所以后续也能获取到在配置变更之前维护的ViewModelStore
,所以配置变更前后获取到的ViewModelStore
、ViewModel
实例不变。
Fragment
@NonNull
@Override
public ViewModelStore getViewModelStore() {
if (mFragmentManager == null) {
// 不能从detached的Fragment访问ViewModels
throw new IllegalStateException("Can't access ViewModels from detached fragment");
}
if (getMinimumMaxLifecycleState() == Lifecycle.State.INITIALIZED.ordinal()) {
throw new IllegalStateException("Calling getViewModelStore() before a Fragment "
+ "reaches onCreate() when using setMaxLifecycle(INITIALIZED) is not "
+ "supported");
}
return mFragmentManager.getViewModelStore(this);
}
mFragmentManager
为FragmentManager
,我们来看下其getViewModelStore()
方法。
FragmentManager --> getViewModelStore方法
@NonNull
ViewModelStore getViewModelStore(@NonNull Fragment f) {
return mNonConfig.getViewModelStore(f);
}
mNonConfig
为FragmentManagerViewModel
,我们先来看一下它是如果创建的,然后再来看一下其getViewModelStore()
方法。
通过查找,发现其在FragmentManager.attachController()
方法内创建。
FragmentManager --> attachController方法
@SuppressWarnings("deprecation")
@SuppressLint("SyntheticAccessor")
void attachController(@NonNull FragmentHostCallback<?> host,
@NonNull FragmentContainer container, @Nullable final Fragment parent) {
...
// Get the FragmentManagerViewModel
if (parent != null) {
// 当parent不为null时,调用父FragmentManager的getChildNonConfig获取。
mNonConfig = parent.mFragmentManager.getChildNonConfig(parent);
} else if (host instanceof ViewModelStoreOwner) {
// 从host中获取ViewModelStore,然后使用FragmentManagerViewModel进行获取。
ViewModelStore viewModelStore = ((ViewModelStoreOwner) host).getViewModelStore();
mNonConfig = FragmentManagerViewModel.getInstance(viewModelStore);
} else {
mNonConfig = new FragmentManagerViewModel(false);
}
...
}
通过查找,发现attachController
方法会在Fragment
的attach
的时候调用,其中host
为FragmentActivity
的内部类FragmentActivity.HostCallbacks
,它实现了ViewModelStoreOwner
接口。
创建mNonConfig
,如果没有父Fragment
,则会从host
中调用getViewModelStore()
方法获取ViewModelStore
,然后调用FragmentManagerViewModel.getInstance(viewModelStore)
进行获取FragmentManagerViewModel
。
因为一般没有父Fragment
,大部分走第二个if
,所以我们先来分析它,我们先来看一下FragmentActivity.HostCallbacks
的getViewModelStore()
方法,然后再来看一下FragmentManagerViewModel
的getInstance()
方法。
FragmentActivity.HostCallbacks --> getViewModelStore方法
class HostCallbacks extends FragmentHostCallback<FragmentActivity> implements
ViewModelStoreOwner,
OnBackPressedDispatcherOwner,
ActivityResultRegistryOwner,
SavedStateRegistryOwner,
FragmentOnAttachListener {
...
@NonNull
@Override
public ViewModelStore getViewModelStore() {
return FragmentActivity.this.getViewModelStore();
}
...
}
FragmentActivity.HostCallbacks
的getViewModelStore()
方法,直接调用了FragmentActivity
的getViewModelStore()
方法,即调用了其父类ComponentActivity
的getViewModelStore()
方法。
所以FragmentManager.attachController()
方法内,通过host
也能获取到ComponentActivity
的ViewModelStore
。
接下来,我们再来看一下FragmentManagerViewModel
的getInstance()
方法。
FragmentManagerViewModel --> getInstance方法
final class FragmentManagerViewModel extends ViewModel {
private static final String TAG = FragmentManager.TAG;
private static final ViewModelProvider.Factory FACTORY = new ViewModelProvider.Factory() {
@NonNull
@Override
@SuppressWarnings("unchecked")
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
FragmentManagerViewModel viewModel = new FragmentManagerViewModel(true);
return (T) viewModel;
}
};
@NonNull
static FragmentManagerViewModel getInstance(ViewModelStore viewModelStore) {
ViewModelProvider viewModelProvider = new ViewModelProvider(viewModelStore,
FACTORY);
return viewModelProvider.get(FragmentManagerViewModel.class);
}
}
FragmentManagerViewModel
是一个ViewModel
,getInstance(ViewModelStore)
方法会先从传入的ViewModelStore
(即ComponentActivity
的ViewModelStore
)中获取,如果没有则使用FACTORY
进行创建FragmentManagerViewModel
。
说明:
- 传入的
ViewModelStore
为ComponentActivity
的ViewModelStore
,一开始ViewModelStore
内是没有FragmentManagerViewModel
的,所以创建FragmentManagerViewModel
并存入其ComponentActivity
的ViewModelStore
中。- 由于
ComponentActivity
的ViewModelStore
配置变更后实例不变,所以FragmentManagerViewModel.getInstance()
方法也能从ComponentActivity
的ViewModelStore
中获取到配置变更前存入的FragmentManagerViewModel
实例。
说完了FragmentManagerViewModel
的创建,我们再来看一下其getViewModelStore()
方法。
FragmentManagerViewModel --> getViewModelStore方法
@NonNull
ViewModelStore getViewModelStore(@NonNull Fragment f) {
ViewModelStore viewModelStore = mViewModelStores.get(f.mWho);
if (viewModelStore == null) {
viewModelStore = new ViewModelStore();
mViewModelStores.put(f.mWho, viewModelStore);
}
return viewModelStore;
}
getViewModelStore(Fragment)
方法,获取到指定Fragment
的ViewModelStore
,如果没有则进行创建并保存到mViewModelStores
中,mViewModelStores
为ViewModelStore
的Map
集合。
说明:
- 为什么
FragmentManagerViewModel.getViewModelStore(Fragment)
方法,要传入Fragment
才能获取到ViewModelStore
?
- 因为
FragmentManagerViewModel
,保存到了ComponentActivity
的ViewModelStore
中,所以每个Fragment
获取到的FragmentManagerViewModel
实例相同,所以需要传入Fragment
实例区分是获取ViewModelStore
集合的哪个。
- 为什么
Fragment
在配置变更前后获取到的ViewModelStore
、ViewModel
实例不变?
- 因为
ComponentActivity
在配置变更前后获取到的ViewModelStore
、ViewModel
实例不变,所以存在ComponentActivity
的ViewModelStore
中的FragmentManagerViewModel
实例不变,所以存在mViewModelStores
的各个Fragment
的ViewModelStore
实例不变,所以ViewModel
实例不变。
代码流程:
Fragment
的attach
的时候,获取到了ComponentActivity
的ViewModelStore
,创建FragmentManagerViewModel
并存入到ComponentActivity
的ViewModelStore
中。FragmentManagerViewModel.getViewModelStore(Fragment)
方法,通过Fragment
从mViewModelStores
中获取到对应的ViewModelStore
,如果没有则进行创建后保存到mViewModelStores
中。
ViewModel是如何被清除的?
要想分析ViewModel
是如何被清除的,则需要分析ViewModelStore
是如何被清除的。
Activity
通过引用查找,我们发现在ComponentActivity
的构造方法里面调用了ViewModelStore
的清除操作。
ComponentActivity类
public ComponentActivity() {
Lifecycle lifecycle = getLifecycle();
//noinspection ConstantConditions
if (lifecycle == null) {
throw new IllegalStateException("getLifecycle() returned null in ComponentActivity's "
+ "constructor. Please make sure you are lazily constructing your Lifecycle "
+ "in the first call to getLifecycle() rather than relying on field "
+ "initialization.");
}
...
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_DESTROY) {
// Clear out the available context
mContextAwareHelper.clearAvailableContext();
// And clear the ViewModelStore
if (!isChangingConfigurations()) {
// 不是配置变更,清除全部ViewModel。
getViewModelStore().clear();
}
}
}
});
...
}
使用Lifecycle
观察当前生命周期的状态,如果事件处于ON_DESTROY
并且不是配置变更,则清空全部ViewModel
。
说明:
Activity
的ViewModel
是如何被清除的?
- 使用
Lifecycle
观察当前生命周期的状态,如果事件处于ON_DESTROY
并且不是配置变更,则清空全部ViewModel
。
Fragment
通过引用查找,我们发现在FragmentManagerViewModel
的clearNonConfigStateInternal
方法里面调用了ViewModelStore
的清除操作。
FragmentManagerViewModel --> clearNonConfigStateInternal方法
void clearNonConfigState(@NonNull Fragment f) {
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "Clearing non-config state for " + f);
}
clearNonConfigStateInternal(f.mWho);
}
void clearNonConfigState(@NonNull String who) {
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "Clearing non-config state for saved state of Fragment " + who);
}
clearNonConfigStateInternal(who);
}
private void clearNonConfigStateInternal(@NonNull String who) {
// Clear and remove the Fragment's child non config state
FragmentManagerViewModel childNonConfig = mChildNonConfigs.get(who);
if (childNonConfig != null) {
childNonConfig.onCleared();
mChildNonConfigs.remove(who);
}
// Clear and remove the Fragment's ViewModelStore
// 获取到对应Fragment的ViewModelStore
ViewModelStore viewModelStore = mViewModelStores.get(who);
if (viewModelStore != null) {
// 清除全部ViewModel。
viewModelStore.clear();
mViewModelStores.remove(who);
}
}
clearNonConfigStateInternal(String)
方法,会获取到对应Fragment
的ViewModelStore
,然后调用其clear()
方法清除全部ViewModel
。
通过引用查找,我们发现在clearNonConfigStateInternal(String)
方法被clearNonConfigState(Fragment)
、clearNonConfigState(String)
方法调用,然后它两又被几处调用,最后通过Debug
发现FragmentStateManager.destroy()
方法,执行了clearNonConfigState(Fragment)
方法。
FragmentStateManager --> destroy方法
void destroy() {
...
if (shouldDestroy) {
FragmentHostCallback<?> host = mFragment.mHost;
boolean shouldClear;
if (host instanceof ViewModelStoreOwner) {
shouldClear = mFragmentStore.getNonConfig().isCleared();
} else if (host.getContext() instanceof Activity) {
Activity activity = (Activity) host.getContext();
shouldClear = !activity.isChangingConfigurations();
} else {
shouldClear = true;
}
if ((beingRemoved && !mFragment.mBeingSaved) || shouldClear) {
// 执行FragmentManagerViewModel的clearNonConfigState(Fragment),清除不会因配置变更而改变的状态。
mFragmentStore.getNonConfig().clearNonConfigState(mFragment);
}
...
}
...
}
host
为FragmentActivity.HostCallbacks
,它实现了ViewModelStoreOwner
接口,所以会走第一个if
。只要shouldClear
为true
的时候,就会执行到FragmentManagerViewModel
的clearNonConfigState(Fragment)
方法,我们来看一下FragmentManagerViewModel
的isCleared()
方法的返回值是什么?
FragmentManagerViewModel --> isCleared方法
final class FragmentManagerViewModel extends ViewModel {
@Override
protected void onCleared() {
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "onCleared called for " + this);
}
// 标记已经被清理
mHasBeenCleared = true;
}
boolean isCleared() {
return mHasBeenCleared;
}
}
FragmentManagerViewModel
是一个ViewModel
,被添加到了ComponentActivity
的ViewModelStore
中,当ComponentActivity
的ViewModelStore
被清除的时候(事件为ON_DESTROY
并且不是配置变更),会调用ViewModel
的onCleared()
方法,则mHasBeenCleared
为true
,即isCleared()
方法返回为true
。
因为isCleared()
方法返回为true
,所以FragmentStateManager.destroy()
方法内会执行到FragmentManagerViewModel
的clearNonConfigState(Fragment)
方法,会获取到对应Fragment
的ViewModelStore
,然后调用其clear()
方法清除全部ViewModel
。
说明:
Fragment
的ViewModel
是如何被清除的?
FragmentManagerViewModel
是一个ViewModel
,被添加到了ComponentActivity
的ViewModelStore
中,当ComponentActivity
的ViewModelStore
被清除的时候(事件为ON_DESTROY
并且不是配置变更),会调用ViewModel
的onCleared()
方法,则mHasBeenCleared
为true
,即isCleared()
方法返回为true
,所以FragmentStateManager.destroy()
方法内会执行到FragmentManagerViewModel
的clearNonConfigState(Fragment)
方法,会获取到对应Fragment
的ViewModelStore
,然后调用其clear()
方法清除全部ViewModel
。
总结
以上就是全面的Jetpack-ViewModel
源码了!之后会出Jetpack
其它源码系列,请及时关注。如果你有什么问题,大家评论区见!
最后推荐一下我的网站,开发者的技术博客: devbolg.cn ,目前包含android相关的技术,之后会面向全部开发者,欢迎大家来体验!
网友评论