jetpack系列再看lifecycle实现原理细节

在21年时候有写过一次lifecycle: https://www.jianshu.com/p/838631cdf520。时隔两三年了刚好最近在看jetpack相关的一些库。回顾下lifecycle实现源码. 现在再来看感受又不一样,之前可能注重他的流程。现在更多关注他的实现细节和为什么这么设计,这样设计的好处是什么,可能多些自己的思考吧。

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模式管理生命周期防止业务开发同学忘记手动释放资源。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容