ViewModelScope是viewModel的管理者,而ViewModelProvider是ViewModel的间接管理者。
咱们个别应用的时候都是ViewModel持有LiveData
应用
咱们个别获取ViewModel对象都是应用ViewModelProvider的get()办法。
在Activity或者Fragment 里调用
val viewProvider:ViewModelProvider = ViewModelProvider(MainActivity@this)val viewModel:MainViewModel = viewProvider .get(MainViewModel::class.java)
首先失去ViewModelProvider对象
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) { this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory ? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory() : NewInstanceFactory.getInstance());}
get办法
public <T extends ViewModel> T get(@NonNull Class<T> modelClass) { //取出modelClass的全限定名 String canonicalName = modelClass.getCanonicalName(); if (canonicalName == null) { throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels"); } // DEFAULT_KEY ="androidx.lifecycle.ViewModelProvider.DefaultKey" //生成新的Key return get(DEFAULT_KEY + ":" + canonicalName, modelClass);}
最终调用
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) { ViewModel viewModel = mViewModelStore.get(key); if (modelClass.isInstance(viewModel)) { if (mFactory instanceof OnRequeryFactory) { ((OnRequeryFactory) mFactory).onRequery(viewModel); } return (T) viewModel; } else { //noinspection StatementWithEmptyBody if (viewModel != null) { // TODO: log a warning. } } if (mFactory instanceof KeyedFactory) { viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass); } else { viewModel = (mFactory).create(modelClass); } mViewModelStore.put(key, viewModel); return (T) viewModel;}
能够咱们传递的是一个
ViewModelStoreOwner对象
Fragment或者Activity就是这样一个对象,因为他们实现了`
ViewModelStoreOwner接口。
就拿Activity的父类ComponentActivity来举例。
public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner, ViewModelStoreOwner, HasDefaultViewModelProviderFactory, SavedStateRegistryOwner, OnBackPressedDispatcherOwner {
它的getViewModelStore办法实现如下:
@NonNull@Overridepublic 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 nc = (NonConfigurationInstances) getLastNonConfigurationInstance(); if (nc != null) { // Restore the ViewModelStore from NonConfigurationInstances mViewModelStore = nc.viewModelStore; } if (mViewModelStore == null) { mViewModelStore = new ViewModelStore(); } } return mViewModelStore;}
看下ViewModelStore的实现
public class ViewModelStore { // 一个存储ViewModel的hashMap. private final HashMap<String, ViewModel> mMap = new HashMap<>(); //如果以后曾经蕴含ViewModel了,替换就的ViewModel,并回调其onCleared办法。 //这个办法在只在ViewModelProvieder的get办法中调用,当ViewModelProvieder从本人的ViewModelScore中无奈获取ViewModel对象时,它会new一个新的,而后退出本人的ViewModelScore中。 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); } Set<String> keys() { return new HashSet<>(mMap.keySet()); } /** * Clears internal storage and notifies ViewModels that they are no longer used. */ public final void clear() { for (ViewModel vm : mMap.values()) { vm.clear(); } mMap.clear(); }}
生命周期
ViewModel会在Activity Destroy是清空本人
在ComponentActivity的构造方法中Activity会监听本人的申明周期的ON_DESTROY工夫。而咱们的Activity都继承自ComponentActivity。
getLifecycle().addObserver(new LifecycleEventObserver() { @Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { if (event == Lifecycle.Event.ON_DESTROY) { //如果是配置扭转,比方屏幕旋转等导致的销毁,不会回调ViewModel的clear()办法。 if (!isChangingConfigurations()) { getViewModelStore().clear(); } } }});
这样,当Activity销毁时,ViewModel就能够在本人的onCleared()办法中做一些清空数据的工作,防止的内存泄露。