JetPack | Lifecycle 如何做到感知生命周期

LifeCycle的作用是什么:生命周期感知型组件可执行操作来响应另一个组件(如 Activity 和 Fragment)的生命周期状态的变化。这些组件有助于您编写出更有条理且往往更精简的代码,此类代码更易于维护(摘自Android官网的解释)。 Lifecycle 最早是在 support 26.1.0 时被引入的,目前已经成为源码的一部分,而几乎无需使用者在 Gradle 额外地配置依赖。 Lifecycle的出现,可以帮助我们感知生命周期。

关于LifeCycle的使用这里不在复述直接看官方文档,本篇文章旨在理解Lifecycle的本质以及优秀代码的设计思想。

Lifecycle出现的背景原因

在LifeCycle没有出现之前,如果外部类要先监听Activity/Fragment的生命周期,需要定义个接口来监听Activity的生命周期方法(onCreate onStart onResume)等。避免内存泄漏等问题。 如下代码:随着Activity的功能越来越复杂,Listener处理的事情就会越来越多,最终导致代码难以维护。

class MyLocationListener {
    public MyLocationListener(Context context, Callback callback) {
        // ...
    }

    void start() {
        // connect to system location service
    }

    void stop() {
        // disconnect from system location service
    }
}

class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    @Override
    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, (location) -> {
            // update UI
        });
    }

    @Override
    public void onStart() {
        super.onStart();
        myLocationListener.start();
        // manage other components that need to respond
        // to the activity lifecycle
    }

    @Override
    public void onStop() {
        super.onStop();
        myLocationListener.stop();
        // manage other components that need to respond
        // to the activity lifecycle
    }
}

那么Lifecycle是如何实现组件的隔离呢?

Lifecycle 实现隔离

在Android的官方文档中看到有两个关键的接口LifecycleOwner 表示该类具有LifecycleLifecycleObserver** 监听生命周期事件** 以及 [LifecycleRegistry](https://developer.android.com/reference/androidx/lifecycle/LifecycleRegistry?hl=zh-cn) **将生命周期事件转发 ** 下面我们来自定义LifecycleOwner来实现Lifecycle的完整流转。

image.png

open class LActivity:Activity(),LifecycleOwner {

    /**
     * 负责转发生命周期事件
     */
    private var mFragmentLifecycleRegistry = LifecycleRegistry(this)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
    }

    override fun onStart() {
        super.onStart()
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
    }

    override fun onResume() {
        super.onResume()
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
    }

    override fun onStop() {
        super.onStop()
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
    }

    override fun onDestroy() {
        super.onDestroy()
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    }

    override fun getLifecycle(): Lifecycle {
        return mFragmentLifecycleRegistry
    }
}

LifecycleEventObserver监听生命周期:

class LifecycleActivity : LActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_lifecycle)
        //感知生命周期
        lifecycle.addObserver(MyLifecycleObserver())
    }
}

/**
 * 监听生命周期
 */
class MyLifecycleObserver:LifecycleEventObserver{
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        Log.e("MyLifecycleObserver", "onStateChanged: ${source.lifecycle.currentState} event:${event}" )
    }
}

运行结果如下:Lifecycle的事件以及状态的对应关系
image.png

在Android的官方文档 给出的事件和状态的关系,如下图和我们上述的是一致的。 事件是监听生命周期的而状态是判断页面是否处于激活状态。

ON_CREATE 和 ON_STOP 对应着CREATED。ON_START和ON_PAUSE对应着STARTED。这样的状态对应是因为ON_PAUSE有重走onStart的潜力,而ON_STOP有重走onCreate的潜力

image.png

那么Lifecycle为什么要设计事件和状态呢?

Lifecycle事件和状态的对应关系

  • event:实现了 LifecycleObserver 的第三方组件,能够在 onCreateonDestroy 等 event 方法内完成对生命周期的监听,event 是针对 第三方组件内部作为观察者,来观察 页面对组件的推送。
  • state :的存在,主要是 为了方便使用者判断 页面是否处于激活状态,以便实现生命周期安全的通知,state 是针对 页面作为观察者,来观察 来自第三方组件内部对页面的推送,那么此时通过 state 的判断,我们可确保在页面处于非激活状态时不收到 基于 LifeCycle 的组件(比如 LiveData)的推送。

LiveData是根据State来判断生命周期是否处于活跃状态的,如下代码:

lifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)

只有 onResume 和 onPause 是介于 STARTED、RESUMED 状态之间,也即 只有这两个生命周期节点 100% 确定能收到 LiveData 的推送(FragmentActivity 额外支持 onStart 期间的接收)。

LifecycleRegistry 核心类

LifecycleRegistry 的设计如何去分发事件。其实看到源码可以和LiveData的分发消息差不多。

image.png

如下代码:通过handleLifecycleEvent发送生命周期事件

   // 分发生命周期事件 
   public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        enforceMainThreadIfNeeded("handleLifecycleEvent");
        moveToState(event.getTargetState());
    }

    private void moveToState(State next) {
        ......
        sync();
        ......
    }
    
    private void sync() {
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
        ....
        while (!isSynced()) {
            mNewEventOccurred = false;
            if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
                backwardPass(lifecycleOwner);
            }
            Map.Entry newest =
                mObserverMap.newest();
            if (!mNewEventOccurred && newest != null
                    && mState.compareTo(newest.getValue().mState) > 0) {
                forwardPass(lifecycleOwner);
            }
        }
        mNewEventOccurred = false;
    }

sync()方法分别调用了forwardPassbackwardPass进行分发生命周期事件。 监听生命周期事件及状态: mObserverMap 存储监听ObserverWithState

    private FastSafeIterableMap mObserverMap =
            new FastSafeIterableMap<>();

addObserver 添加监听事件,将obsever包装成ObserverWithState(这一段代码和LiveData中的observer类似)

    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
        enforceMainThreadIfNeeded("addObserver");
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        //observer 包装ObserverWithState
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        //mObserverMap 存储statefulObserver
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

        //.......
        boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
        State targetState = calculateTargetState(observer);
        mAddingObserverCounter++;
        //重复addObserver 会返回之前的状态
        while ((statefulObserver.mState.compareTo(targetState) < 0
                && mObserverMap.contains(observer))) {
            pushParentState(statefulObserver.mState);
            final Event event = Event.upFrom(statefulObserver.mState);
            if (event == null) {
                throw new IllegalStateException("no event up from " + statefulObserver.mState);
            }
            //发送生命周期事件
            statefulObserver.dispatchEvent(lifecycleOwner, event);
            popParentState();
            // mState / subling may have been changed recalculate
            targetState = calculateTargetState(observer);
        }

        if (!isReentrance) {
            // we do sync only on the top level.
            sync();
        }
        mAddingObserverCounter--;
    }

ObserverWithState包装类通过dispatchEvent,在通过mLifecycleObserver.onStateChanged分发事件

    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;
        }
    }

你可能感兴趣的:(JetPack | Lifecycle 如何做到感知生命周期)