预备知识
在Android
中我知道Activity
有一个onSaveInstanceState
函数,用于在Activity
在不幸被回收或者配置改变时存储序列化对象,在下次重建时onRestoreInstanceState
取出序列化数据.
要是我们有非序列数据呢?
public Object onRetainNonConfigurationInstance
和public Object getLastNonConfigurationInstance()
可以帮助我存储任意非序列化数据,用于下次重建复用对象
onRetainNonConfigurationInstance
class Activity
public Object onRetainNonConfigurationInstance() {
return null;
}
}
该函数在onStop
和onDestry
之间回调,你可以返回任意对象,该对象会在下次重建Activity调用getLastNonConfigurationInstance
获得.
我们看下一个demo:
class Person {
}
class MainActivity : Activity() {
var myString: Person? = null
private val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val lastNonConfigurationInstance = lastNonConfigurationInstance
if (lastNonConfigurationInstance != null) {
Log.e(TAG, "onCreate: lastNonConfigurationInstance hash:" + lastNonConfigurationInstance + "")
myString = lastNonConfigurationInstance as Person
}
if (myString == null) {
myString = Person()
}
Log.e(TAG, "onCreate: myString hash:" + myString + "")
}
override fun onRetainNonConfigurationInstance(): Person? {
return myString
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
}
}
输出
onCreate: myString hash:com.example.leakstudy.Person@2b4aece1
进行旋转屏幕(Activity会重建)
//重建前
onCreate: myString hash:com.example.leakstudy.Person@2b4aece1
//重建后
onCreate: lastNonConfigurationInstance hash:com.example.leakstudy.Person@2b4aece1
onCreate: myString hash:com.example.leakstudy.Person@2b4aece1
而我们的viewmodel便是利用这一特性完成存储.
ViewModelStore的存储
ViewModelStoreOwner
是一个重要的接口,且声明如下:
public interface ViewModelStoreOwner {
@NonNull
ViewModelStore getViewModelStore();
}
实现ViewModelStoreOwner
接口的对象必须在configration
改变时存储好自己ViewModelStore
对象,并且在这个对象被回收时候调用ViewModelStore
的onClear
函数,而ComponentActivity
对象便实现了这个接口.
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
ViewModelStoreOwner,
我们在看一下ViewModelStore
public class ViewModelStore {
//存储所有的viewModel,键为ViewModel的全类名.
private final HashMap<String, ViewModel> mMap = new HashMap<>();
//放一个新的viewmodel
final void put(String key, ViewModel viewModel) {
ViewModel oldViewModel = mMap.put(key, viewModel);
//如果存在旧元素那么调用oncreard
if (oldViewModel != null) {
oldViewModel.onCleared();
}
}
final ViewModel get(String key) {
return mMap.get(key);
}
Set<String> keys() {
return new HashSet<>(mMap.keySet());
}
/**
* 调用所有的viewmodel 的clear函数
*/
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.clear();
}
mMap.clear();
}
}
我们继续研究ComponentActivity
的实现
//ComponentActivity.java
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
ViewModelStoreOwner{
static final class NonConfigurationInstances {
Object custom;
ViewModelStore viewModelStore;
}
private ViewModelStore mViewModelStore;
NonConfigurationInstances mLastNonConfigurationInstances;
//activity在回收或者改变时configration存储数据
public final Object onRetainNonConfigurationInstance() {
Object custom = onRetainCustomNonConfigurationInstance();
//将viewmodel存储到NonConfigurationInstances对象中
ViewModelStore viewModelStore = mViewModelStore;
if (viewModelStore == null) {
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;
}
//我们看下如何返回viewmodel
@Override
public ViewModelStore getViewModelStore() {
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;
}
}
我们知道viewmodel
会在activity
被意外非回收销毁时会调用Viewmodel.onCleared
函数,而Viewmodel.onCleared
是被mViewModelStore.clear
回调的.但是我们需要区分调用Destroy
是否需要考虑复用的情况,也是正常销毁还是回收在售后重建.
public ComponentActivity() {
Lifecycle lifecycle = getLifecycle();
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
//on_Destroy的根据是否是配置改变确定是否需要调用clear函数
if (event == Lifecycle.Event.ON_DESTROY) {
if (!isChangingConfigurations()) {
getViewModelStore().clear();
}
}
}
});
//mChangingConfigurations会在onstop时候进行判断
public boolean isChangingConfigurations() {
//mChangingConfigurations位于activity
return mChangingConfigurations;
}
}
ViewModel的创建
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val viewModelProvider = ViewModelProvider(this, AndroidViewModelFactory(this.application))
val viewModel = viewModelProvider.get(MyViewModel::class.java)
println("MainActivity.onCreate")
}
}
//ViewModelProvider.java
public class ViewModelProvider {
public interface Factory {
<T extends ViewModel> T create(@NonNull Class<T> modelClass);
}
}
public class ViewModelProvider {
private final Factory mFactory;
private final ViewModelStore mViewModelStore;
public ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory) {
this(owner.getViewModelStore(), factory);
}
public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {
mFactory = factory;
mViewModelStore = store;
}
//获取viewmodel实例
public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {
String canonicalName = modelClass.getCanonicalName();
return get(DEFAULT_KEY + ":" + canonicalName, modelClass);
}
//最终调用这
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
//如果mViewModelStore没有存储这个viewmodel,将返回null
ViewModel viewModel = mViewModelStore.get(key);
//model有可能是空,如果是空必然返回false
if (modelClass.isInstance(viewModel)) {
return (T) viewModel;
} else {
//预留代码
if (viewModel != null) {
}
}
//判断传入的factory类型,我们这里直接看false即可
if (mFactory instanceof KeyedFactory) {
viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
} else {
//调用factory.create完成viewmodel
viewModel = (mFactory).create(modelClass);
}
//将创建的viewimodel放入mViewModelStore
mViewModelStore.put(key, viewModel);
return (T) viewModel;
}
}
我们最后看一个库里一个默认实现AndroidViewModelFactory
.
public static class AndroidViewModelFactory extends ViewModelProvider.NewInstanceFactory {
private static AndroidViewModelFactory sInstance;
@NonNull
public static AndroidViewModelFactory getInstance(@NonNull Application application) {
if (sInstance == null) {
sInstance = new AndroidViewModelFactory(application);
}
return sInstance;
}
private Application mApplication;
public AndroidViewModelFactory(@NonNull Application application) {
mApplication = application;
}
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
//当前modelClass类是AndroidViewModel或者父类
if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
try {
//返回新的实例对象
return modelClass.getConstructor(Application.class).newInstance(mApplication);
} catch (NoSuchMethodException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (InstantiationException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (InvocationTargetException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
}
}
//super.create是利用空构造函数实现的
return super.create(modelClass);
}
}
viewmodel
整体比较简单.