本文讲的是lifecycle、viewmodel、livedata的简单原理~
先来段小结
Lifecycle原理:
Lifecycle可以用来观察activity和fragment的生命周期。
- 在api>=29之前,activity是通过执行生命周期的时候回调LifecyclerCallbacks;29之后,activity会添加一个没有UI的ReportFragment,间接获得Activity的生命周期事件后,通过LifecycleRegistry用接收到的event计算出当前state保存下来并给每个观察者发送通知事件,观察者是一个封装的带state的ObserverWithState类。
- Fragment是直接在生命周期里调用LifecycleRegistry分发事件。
ViewModel原理:
- 在activity销毁的时候会执行onRetainNonConfigurationInstance方法,在这个方法里保存Activity、fragment、和子fragment的viewmodel到viewmodelStore的hashmap里,然后在Activity恢复的时候用getLastNonConfigurationInstance方法里通过key从hashmap再取出Viewmodel。
- Viewmodel通过lifecycle监听Activity的生命周期变化,在Activity创建的时候保证数据取出,销毁时移除所有的viewmodel数据。
Livedata原理:
- 观察者:livedata的observe()会创建一个LifecycleBoundObserver 观察者。通过lifecycle观察activity 的state为destroy的时候把自己移除掉。不是destroy则给自己分发已存储的data粘性数据。
- 被观察者:livedata的setValue会调用dispatchingValue方法遍历所有的观察者回调data。观察者是observe()方法时添加进集合的。postValue()是通过主线程handler调用setValue()。
正式开始
Lifecycle
使用:
//实现了LifecycleOwner 接口的Activity中调用getLifecycle,获得LifecycleRegistry,调用其addObserver().
lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {}
//……
}
原理分析:
LifecycleOwner 接口用于标记其实现类具备 Lifecycle 对象,实现了该接口即意味着实现类具有生命周期。我们日常使用的 androidx.appcompat.app.AppCompatActivity 和 androidx.fragment.app.Fragment 均实现了该接口。
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
public class ComponentActivity|Fragment implements LifecycleOwner {
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}
- 设备的系统版本号大于等于29。会向 Activity 注册一个 LifecycleCallbacks ,以此来直接获得各个生命周期事件的回调。Activity生命周期回调的时候会回调LifecycleCallbacks的对应生命周期方法。
- 设备的系统版本号小于 29。会通过向 Activity 添加一个无 UI 界面的 Fragment(即 ReportFragment),间接获得 Activity 的各个生命周期事件的回调。
- 之所以会进行这两种情况区分,是因为 Activity.registerActivityLifecycleCallbacks 是 SDK 29 开始 android.app.Activity 新添加的方法。
LifecycleRegistry#addObserver:
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//将传入的 observer 对象包装为 ObserverWithState 类型
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
//如果 observer 之前已经传进来过了,则不重复添加,直接返回
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
//如果 LifecycleOwner 对象已经被回收了,则直接返回
return;
}
//如果 isReentrance 为 true,意味着当前存在重入的情况:
//1. mAddingObserverCounter != 0。会出现这种情况,是由于开发者先添加了一个 LifecycleObserver ,当还在向其回调事件的过程中,在回调方法里又再次调用了 addObserver 方法添加了一个新的 LifecycleObserver
//2.mHandlingEvent 为 true。即此时正处于向外回调 Lifecycle.Event 的状态
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
State targetState = calculateTargetState(observer);
//递增加一,标记当前正处于向新添加的 LifecycleObserver 回调 Event 值的过程
mAddingObserverCounter++;
//statefulObserver.mState.compareTo(targetState) < 0 成立的话说明 State 值还没遍历到目标状态
//mObserverMap.contains(observer) 成立的话说明 observer 还没有并移除
//因为有可能在遍历过程中开发者主动在回调方法里将 observer 给移除掉了,所以这里每次循环都检查下
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
//向 observer 回调进入“statefulObserver.mState”前需要收到的 Event 值
//由于当添加 LifecycleObserver 时 Lifecycle 可能已经处于非 INITIALIZED 状态了,所以需要通过循环检查的方式来向 ObserverWithState 逐步下发 Event 值。
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
}
if (!isReentrance) {
sync();
}
mAddingObserverCounter--;
}
ReportFragment:
@Override
public void onStart() {
super.onStart();
dispatchStart(mProcessListener);
dispatch(Lifecycle.Event.ON_START);
}
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
}
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
Fragment 是在其生命周期方法中直接调用了内部LifecycleRegistry的handleLifecycleEvent进行生命周期事件分发。该方法会根据接收到的 Event 值换算出对应的 State 值,然后更新本地的 mState,再向所有 Observer 进行事件通知,最终还是会调用到 ObserverWithState 的 dispatchEvent 方法。
Fragment :
public class Fragment implement LifecycleOwner{
LifecycleRegistry mLifecycleRegistry;
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
void performStart() {
...
onStart();
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
...
}
}
LifecycleRegistry:
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
enforceMainThreadIfNeeded("handleLifecycleEvent");
moveToState(event.getTargetState());
}
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
sync();
mHandlingEvent = false;
}
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle 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;
}
private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
pushParentState(observer.mState);
final Event event = Event.upFrom(observer.mState);
if (event == null) {
throw new IllegalStateException("no event up from " + observer.mState);
}
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
}
}
}
Event 用于抽象 Activity/Fragment 的生命周期事件。例如,当 Activity 的 onCreate 方法被回调时就会被抽象为 ON_CREATE事件。
State 用于标记 Lifecycle 的当前生命周期状态。例如,当 Activity 即将回调 onDestory 方法时则处于 DESTROYED 状态
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = event.getTargetState();
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
参考文章:
lifecycle源码注解拷贝小红军storm 大佬较多,详情移步:
https://www.jianshu.com/p/cc356af30411
Viewmodel
使用场景:
- 场景一:我们开发的 APP 可以转屏,转屏后将触发 Controller(Activity or Fragment) 的重建,为了维护转屏前后数据的一致性,我们要么将需要维护的数据以 Bundle 的形式在 onSaveInstance 中保存,必要的时候需要对复合数据实现繁琐的 Parceable 接口,如果数据量太大则我们必须将数据持久化,在转屏后重新拉取数据(from database or networks);
- 场景二:我们的 Activity 中同时维护了多个 Fragment,每个 Fragment 需要共享一些数据,传统的做法是由宿主 Activity 持有共享数据,并暴露数据获取接口给各个寄生 Fragment。
原理:
ComponentActivity:
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
//观察到 Activity 被销毁
if (event == Lifecycle.Event.ON_DESTROY) {
// Clear out the available context
mContextAwareHelper.clearAvailableContext();
// And clear the ViewModelStore
if (!isChangingConfigurations()) {
getViewModelStore().clear();
}
}
}
});
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
ensureViewModelStore();
getLifecycle().removeObserver(this);
}
});
/**
* Retain all appropriate non-config state. You can NOT
* override this yourself! Use a {@link androidx.lifecycle.ViewModel} if you want to
* retain your own non config state.
*/
@Override
@Nullable
@SuppressWarnings("deprecation")
public final Object onRetainNonConfigurationInstance() {
// Maintain backward compatibility.
Object custom = onRetainCustomNonConfigurationInstance();
ViewModelStore viewModelStore = mViewModelStore;
NonConfigurationInstances nci = new NonConfigurationInstances();
nci.custom = custom;
nci.viewModelStore = viewModelStore;
return nci;
}
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();
}
}
}
- 屏幕旋转前,Activity销毁时:
ComponentActivity调用onRetainNonConfigurationInstance()方法,将要销毁的Activity的mViewModelStore转化为NonConfigurationInstances对象存储。 - 在Activity启动或者再次创建Viewmodel时:
都会调用ensureViewModelStore()方法通过getLastNonConfigurationInstance()恢复mViewModelStore实例对象,最后根据对应的key拿到销毁前对应的ViewModel实例。
处于顶层的 ViewModelStore 依附于 FragmentActivity,它除了保存用户级的 ViewModel 以外,还保存其儿子 Fragment 的 FragmentManagerViewModel。
ViewModelStore 里面就是一个HashMap,用于缓存ViewModel实例对象。
ViewModelStore 与具体的 Controller (Activity or Fragment) 绑定,并与宿主 Controller 俱生俱灭,所以这就解释了为何 ViewModel 与宿主 Controller 的生命周期是一样长了,因为缓存它的 ViewModelStore 与宿主 Controller 寿命相等;
参考文章:
https://www.cnblogs.com/cubbychat/p/15023207.html
Livedata
原理
Livedata:
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
mObservers.putIfAbsent(observer, wrapper);
//LifecycleBoundObserver 是一个观察者,去观察activity的生命周期。当被观察者activity生命周期为destroyed的时候,会执行removeObserver方法,将观察者从Lifecycle被观察者列表中删除。
owner.getLifecycle().addObserver(wrapper);//观察者身份
}
LifecycleBoundObserver :
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {:
final Observer<? super T> mObserver;//父类成员变量
ObserverWrapper(Observer<? super T> observer) {//父类构造方法
mObserver = observer;
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
while (prevState != currentState) {
//粘性事件原因(lifecycle会将livedata.observe()之前的state都分发一次)
activeStateChanged(shouldBeActive());
}
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
//调用livedata的方法分发数据
dispatchingValue(this);//粘性事件分发数据(只分发给当前新加入的Observer)
}
}
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
Livedata:
@MainThread
protected void setValue(T value) {//被观察者身份
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);//观察的值变化时分发数据
}
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
}
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
observer.mObserver.onChanged((T) mData);
}
postValue():就是通过主线程的handler切换到主线程再调用setValue()方法
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
setValue((T) newValue);
}
};
protected void postValue(T value) {
//mMainHandler = createAsync(Looper.getMainLooper());
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}