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
@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 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()办法中做一些清空数据的工作,防止的内存泄露。