LifeCycle
原理:Activity中添加了一个ReportFragment,在fragment的生命周期方法体内调用handleLifecycleEvent,利用反射机制找到对应的注解,执行方法
// ComponentActivity实现了LifecycleOwner接口
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
@NonNull
Lifecycle getLifecycle();
}
// 具体内容
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
ViewModel
Activity实现了ViewModelStoreOwner接口
public interface ViewModelStoreOwner {
/**
* Returns owned {@link ViewModelStore}
*
* @return a {@code ViewModelStore}
*/
@NonNull
ViewModelStore getViewModelStore();
}
// 实现方法
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.");
}
ensureViewModelStore();
return mViewModelStore;
}
void ensureViewModelStore() {
if (mViewModelStore == null) {
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
// Restore the ViewModelStore from NonConfigurationInstances
mViewModelStore = nc.viewModelStore;
}
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
}
}
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();
// configchange情况下,不清除viewmodel
if (!isChangingConfigurations()) {
getViewModelStore().clear();
}
}
}
});
ViewModelStore内部是个HashMap<String, ViewModel>,key重名时,ViewModel会被覆盖,旧的ViewModel被clear。
ViewModel有个onCleared
方法,在ViewModel被销毁时可以进行一些资源清理工作
ViewModelProvider.Factory,主要的功能是用反射机制创建ViewModel实例,ViewModel实例被创建后,只有当ViewModelStoreOwner接口对象DESTORY之后,才会回收。
当你在 Activity 或 Fragment 中使用 by viewModels() 或 ViewModelProvider 来获取 ViewModel 实例时,将其添加到 ViewModelStore 中。
ViewModelStore到底保存到哪里了? 在Activity销毁时,ActivityThread.performDestoryActivity(ActivityClientRecord r,......),其中有r.lastNonConfigurationInstances = retainNonConfigurationInstances()
,最后存储在了ActivityClientRecord中,在Activity重建时,通过attach方法,赋值给 mLastNonConfigurationInstances,这样最终就可以获取到之前的viewmodel了
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
// 默认情况下,第一个状态应该是ON_CREATE,所以可以得出结论,ViewModelStore应该是在onCreate()之后被创建的
ensureViewModelStore();
getLifecycle().removeObserver(this);
}
});
viewModelScope原理
public val ViewModel.viewModelScope: CoroutineScope
get() {
val scope: CoroutineScope? = this.getTag(JOB_KEY)
if (scope != null) {
return scope
}
// 向mBagOfTags添加一个Key为JOB_KEY,value为CloseableCoroutineScope的元素
return setTagIfAbsent(
JOB_KEY,
CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
)
}
internal class CloseableCoroutineScope(context: CoroutineContext) : Closeable, CoroutineScope {
override val coroutineContext: CoroutineContext = context
// activity 或 fragment 处于 DESTORY状态时,会被调用
override fun close() {
coroutineContext.cancel()
}
}
遗留问题
getDefaultViewModelCreationExtras
是干嘛用的
onSaveInstanceState
onSaveInstanceState干了什么?
protected void onSaveInstanceState(@NonNull Bundle outState) {
// 保存视图状态(focus,输入框......)
outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());
// 保存Fragment状态
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
getAutofillClientController().onSaveInstanceState(outState);
dispatchActivitySaveInstanceState(outState);
}
什么时候会执行onSaveInstanceState和onRestoreInstanceState
-
在安卓3.0版本以前,OnSaveInstanceState方法在onPause之前执行
-
在安卓3.0至安卓9.0版本中,如果是未经许可时销毁则OnSaveInstanceState方法在onPause之后,onStop之前执行
-
在安卓9.0之后,如果是未经许可时销毁OnSaveInstanceState方在onStop之后执行
-
OnRestoreInstanceState会在onStart之后执行
场景:按HOME键、切换到其他应用、横竖屏切换
onSaveInstanceState和viewmodel区别
- onSaveInstanceState 用Bundle存储数据便于跨进程传递,而ViewModel 是Object存储数据,不需要跨进程,因此它没有大小限制。
- onSaveInstanceState 在onStop 之后调用,比较频繁。而ViewModel 存储数据是onDestroy 之后。
- onSaveInstanceState 可以选择是否持久化数据到文件里(该功能由ATM 实现,存储到xml里),而ViewModel 没有这功能。
LiveData
多次调用postValue导致数据丢失,原因:mPendingData被赋值后,mPostValueRunnable被post到主线程。等待执行的过程中,postValue被再次调用就会return。解决办法,在主线程调用postValue或者setValue
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
粘性数据问题,即在其他地方注册监听时,会收到最后一次发送的数据
// LiveData注册监听
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
......
// 继续看一下LifecycleRegistry的addObserver()干了什么
owner.getLifecycle().addObserver(wrapper);
}
// LifecycleRegistry注册监听
public void addObserver(@NonNull LifecycleObserver observer) {
// 给observer设置初始状态,DESTROYED 或者 INITIALIZED。只要不是在onCreate函数中注册的observer,添加的时候都会触发onStateChange回调
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// 然后把带初始状态的observer添加到mObserverMap中
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
......
// 同步状态
sync()
}
private void sync() {
// 把当前的State与mObserverMap中所有的observer的State进行对比,如果状态不同,就执行接口回调函数
while (!isSynced()) {
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
// 最后会执行LiveData中的LifecycleBoundObserver的onStateChanged函数
// 最后又调用了LiveData中的considerNotify函数
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
// 核心原因发生在这里,新创建的observer实例,mLastVersion默认是-1,mVersion肯定大于-1,所以就无法return
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
解决办法:添加监听前,用反射修改mVersion的值;开源库UnPeek-LiveData就是在添加监听的时候,直接传入当前的version;用Flow代替