在21年时候有写过一次lifecycle: http://08643.cn/p/838631cdf520。时隔两三年了刚好最近在看jetpack相关的一些库?;毓讼耹ifecycle实现源码. 现在再来看感受又不一样,之前可能注重他的流程。现在更多关注他的实现细节和为什么这么设计,这样设计的好处是什么,可能多些自己的思考吧。
1.总体的流程
lifecycle 整个实现基于观察者模式,比如我们activity就是被观察者,我们自己定义一个观察者 通过addObserver方法 传入观察者,把观察者对象保存在缓存Map中,而在componentActivty中 关联了Actiivty生命周期(29以上Activity LifecycleCallbacks生命周期回调或者空fragment实现。 内部维护了5个状态和6个事件,来保证观察者 被观察者的状态一致,如果不一致会触发执行sync方法从当前被观察者的状态获取事件,观察者分发调用事件,触发onstateChange方法反射调用观察者不同的注解生命周期方法。
2.源码实现
大部分源码在上一篇已经有了,这里主要补充一下新版本特性和一些细节
2.1.被观察者
Lifecycle是一个接口,里面定义了addObsever()、removeObserver、两个枚举State、Event以及根据Event获取State、根据State获取Event的方法 整个框架要用的都定义在里面。实现类是LifecycleRegistry
1.androidx的默认Activity继承了ComponentActivity,而ComponentActivity实现了LifeCycleOwner接口
public class ComponentActivity extends Activity implements
LifecycleOwner,
LifecycleOwner接口里面只提供了getLifecycle方法
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
也正是因为提供了这个方法,他的实现类可以直接调用这个方法,看componentActivity的实现是:
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
return mLifecycleRegistry;
Fragment 类似的也实现了LifecycleOwner接口:
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
ViewModelStoreOwner, SavedStateRegistryOwner {
完成基本介绍后 我们直接看重点ComponentActivity中的onCreate方法:
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
ReportFragment目的就是参考Glide框架添加一个没有UI的fragment到activity上,通过FragmentManager关联,在Activity源码中也能看到生命周期变化会调用FragmentController去dispatch对应fragment生命周期函数.
看到添加方法实现如下,判断版本是否大于29:
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
// On API 29+, we can register for the correct Lifecycle callbacks directly
LifecycleCallbacks.registerIn(activity);
}
// Prior to API 29 and to maintain compatibility with older versions of
// ProcessLifecycleOwner (which may not be updated when lifecycle-runtime is updated and
// need to support activities that don't extend from FragmentActivity from support lib),
// use a framework fragment to get the correct timing of Lifecycle events
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions();
}
}
根据版本判断api29以上注册ActivityLifecycleCallbacks回调监听生命周期,以下的版本添加fragment关联生命周期。主要为了兼容高低版本生命周期变化。
`
最终都会调用 dispatch(activity, Lifecycle.Event.ON_XXX);区别是29以上在回调里面调用,29以下是在ReportFragment生命周期方法中调用
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);
}
}
}
核心代码调用handleLifecycleEvent 里面又调用
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;
}
这里需要注意的是第一个mState == next 判断,也就是观察者lifecycle的状态和被观察者activit的状态如果是一样的,直接不执行后续逻辑,也就不会触发观察者的生命周期方法,
主要还是保证观察者被观察者状态一致,如果不一致则对mstate赋值,再调用sync方法
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;
}
里面代码也比较清晰,如果观察者被观察者状态不一致一致执行循环保证一致,不一致则比较谁的状态值大,分别状态迁移 后移。
Event event = Event.downFrom(observer.mState);
if (event == null) {
throw new IllegalStateException("no event down from " + observer.mState);
}
pushParentState(event.getTargetState());
observer.dispatchEvent(lifecycleOwner, event);
里面其实是根据当前的状态,取出事件类型再调用observer的分发事件 来保持状态一致。而分发事件,核心代码是下面的:
mLifecycleObserver.onStateChanged(owner, event);
onStateChanged接口方法的实现是初始化时候addObsever()时候保存的观察者信息类到
ReflectiveGenericLifecycleObserver
void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) {
invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target);
invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY), source, event,
target);
}
里面用到线程安全的map,key是观察者,value是包装后的对象里面保存了观察者和初始状态
再通过反射调用观察者的对应注解的方法
3.思考和总结
1.为什么涉及mActive变量?
格局出发,mActive设计不知给自己用,还为了给别的框架用。lifecycle虽然是一个组件,更多的是他结合liveData viewModle等一起用,比如liveData在mActive为onStart、onResume才执行一些逻辑 否则直接过滤,保证了一些场景安全,页面都关了网络请求回来刷新数据。
2.为什么要把状态涉及为复用的?
个人猜测是为了减少状态的值少两个,同时区分开Activity的本身状态。如果定义了和Activit生命周期一样的状态,感觉会比较重复,但是又为了记录当前状态。
3.里面设计思想?设计模式?
源码里面真的是大量使用设计模式,这里用到观察者模式、建造者模式、享元、装饰、模版方法、工厂、单例很多都涉及到了。不一一举例。
4.ReportFragment的injectIfNeededIn方法为什么要区分29以上版本
API 29 或以上版本进行区分的原因主要在于 Android 对 Fragment 的管理和生命周期有所变化
以前的版本中,ReportFragment 需要用老的 android.app.Fragment 来保证与老的 lifecycle-runtime 的兼容性。
从 API 29 开始,Android 引入了新的 Fragment API(androidx.fragment.app.Fragment),并且对 Fragment 生命周期进行了优化,当 Activity 调用 onStop 时,Fragment 的 onStop 会先于 Activity 的 onStop 被调用,这样就可以在 Fragment 中更早地保存状态。而在 API 29 之前,Fragment 的 onStop 是在 Activity 的 onStop 之后调用的。
5.使用场景如何,用起来是否方便
一般结合LiveData viewModle使用,上家公司也直接结合MVP模式管理生命周期防止业务开发同学忘记手动释放资源。