LifeCycle详解

1,087 阅读4分钟

一:概念

生命周期感知型组件可执行操作来响应另一个组件(如 Activity 和 Fragment)的生命周期状态的变化。这些组件有助于您写出更有条理且往往更精简的代码,这样的代码更易于维护。

二:用法

1:依赖

implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version" 最新版本为2.3.0

2:使用

以前如果一个组件或者方法想跟Activity 和 Fragment有生命周期的关联,就得通过下面这种方法在各个生命周期里面调用,但是这种模式会导致代码条理性很差而且会扩散错误。

internal class MyLocationListener(
        private val context: Context,
        private val callback: (Location) -> Unit
) {

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

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

class MyActivity : AppCompatActivity() {
    private lateinit var myLocationListener: MyLocationListener

    override fun onCreate(...) {
        myLocationListener = MyLocationListener(this) { location ->
            // update UI
        }
    }

    public override fun onStart() {
        super.onStart()
        myLocationListener.start()
        // manage other components that need to respond
        // to the activity lifecycle
    }

    public override fun onStop() {
        super.onStop()
        myLocationListener.stop()
        // manage other components that need to respond
        // to the activity lifecycle
    }
}

现在有了生命周期组件就有了新的方式,androidx.lifecycle 软件包提供了可用于构建生命周期感知型组件的类和接口 - 这些组件可以根据 Activity 或 Fragment 的当前生命周期状态自动调整其行为。

class MyActivity : AppCompatActivity() {
    private lateinit var myLocationListener: MyLocationListener

    override fun onCreate(...) {
        myLocationListener = MyLocationListener(this, lifecycle) { location ->
            // update UI
        }
        Util.checkUserStatus { result ->
            if (result) {
                myLocationListener.enable()
            }
        }
    }
}

internal class MyLocationListener(
        private val context: Context,
        private val lifecycle: Lifecycle,
        private val callback: (Location) -> Unit
): LifecycleObserver {

    private var enabled = false

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun start() {
        if (enabled) {
            // connect
        }
    }

    fun enable() {
        enabled = true
        if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
            // connect if not connected
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun stop() {
        // disconnect if connected
    }
}

可以看到MyLocationListener实现了LifecycleObserver接口,然后对应方法添加了 @OnLifecycleEvent(Lifecycle.Event.ON_START) 注解,里面写了方法逻辑所需的生命周期。然后在MyActivity初始化对象,传入了context、lifecycle、函数参数。那么这个lifecycle是哪里来的呢 ,明明没有定义这个参数呀。

三:原理

众所周知,如果A要知道B的情况,但A自己没时间去盯着B,那就必须要找一个C来盯着他,当B变化时C去告诉A。这在程序中就是观察者模式。在上面的类中MyLocationListener就是A,它要知道MyActivity的情况,所以实现了LifecycleObserver就变成观察者了。MyActivity就是被观察者。那谁是B呢,谁是通知者呢,在这里自然就是LifeCycle组件了。

lifecycle点进去,会发现进入了ComponentActivity里面,这个activity的继承和实现类如下

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        LifecycleOwner,
        ViewModelStoreOwner,
        SavedStateRegistryOwner,
        OnBackPressedDispatcherOwner 

而这个lifecycle是一个LifecycleRegistry实例对象。

private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@NonNull
@Override
public Lifecycle getLifecycle() {
   return mLifecycleRegistry;
}

我们查看ComponentActivity代码会发现在onCreate方法里面有ReportFragment.injectIfNeededIn(this),点进去可以发现这个fragment就是用来监听ComponentActivity的生命周期的。

 public static void injectIfNeededIn(Activity activity) {
        // ProcessLifecycleOwner should always correctly work and some activities may not extend
        // FragmentActivity from support lib, so we use framework fragments for activities
        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();
        }
    }
    。。。省略代码
     @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        dispatchCreate(mProcessListener);
        dispatch(Lifecycle.Event.ON_CREATE);
    }

    @Override
    public void onStart() {
        super.onStart();
        dispatchStart(mProcessListener);
        dispatch(Lifecycle.Event.ON_START);
    }

    @Override
    public void onResume() {
        super.onResume();
        dispatchResume(mProcessListener);
        dispatch(Lifecycle.Event.ON_RESUME);
    }
     。。。省略代码

通过创建一个无布局fragment绑定到activity中,监听activity的生命周期,并调用dispatch方法。我们进去看看这个方法的实现逻辑

 private void dispatch(Lifecycle.Event event) {
        Activity activity = getActivity();
        if (activity instanceof LifecycleRegistryOwner) { //已废弃 LifecycleRegistryOwner
            ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
            return;
        }

        if (activity instanceof LifecycleOwner) {
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
            if (lifecycle instanceof LifecycleRegistry) {
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
            }
        }
    }

可以看到分情况判断,但第一种情况已经过期了,所以现在只有一种情况,就是LifecycleRegistry.handleLifecycleEvent(event)。这个方法就是判断当前生命周期是什么,然后根据生命周期调用sync方法

 // happens only on the top of stack (never in reentrance),
    // so it doesn't have to take in account parents
    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);
            }
            Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
            if (!mNewEventOccurred && newest != null
                    && mState.compareTo(newest.getValue().mState) > 0) {
                forwardPass(lifecycleOwner);
            }
        }
        mNewEventOccurred = false;
    }

方法里面通过判断当前生命周期与mObserverMap里面数据的生命周期比较判断调用逻辑。这个mObserverMap是一个map集合,里面保存了所有的观察者,数据根据生命周期排序。

 private void backwardPass(LifecycleOwner lifecycleOwner) {
        Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
                mObserverMap.descendingIterator();
        while (descendingIterator.hasNext() && !mNewEventOccurred) {
            Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
            ObserverWithState observer = entry.getValue();
            while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                Event event = downEvent(observer.mState);
                pushParentState(getStateAfter(event));
                observer.dispatchEvent(lifecycleOwner, event);
                popParentState();
            }
        }
}
private void forwardPass(LifecycleOwner lifecycleOwner) {
        Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
                mObserverMap.iteratorWithAdditions();
        while (ascendingIterator.hasNext() && !mNewEventOccurred) {
            Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
            ObserverWithState observer = entry.getValue();
            while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                pushParentState(observer.mState);
                observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
                popParentState();
            }
        }
    }    
     

我们发现,不管是那种方法最后调用的逻辑都是一样的,都是调用observer.dispatchEvent。那这个observer是什么呢,这个observer就是实现了LifecycleObserver的实例对象。

四:总结

可能自己还是写的太少,或者不是很懂,感觉写的很干燥,下次多练练,多看看在写