Android 构建可管理生命周期的应用(一)

LifecycleOwner

LifecycleOwner 是一个接口,表示某个类拥有一个 Lifecycle。它的主要职责是提供对 Lifecycle 对象的访问。实现 LifecycleOwner 接口的类需要返回一个 Lifecycle 实例,该实例描述了其实现类的生命周期状态变化。

  • 常见的 LifecycleOwner 实现:

    • AppCompatActivity
    • Fragment

通过实现 LifecycleOwner,这些组件可以通知其他对象它们的生命周期事件(如 ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY),使得这些对象可以根据宿主组件的生命周期来调整自己的行为。

LifecycleRegistry

LifecycleRegistryLifecycle 类的一个具体实现,它提供了管理生命周期状态的方法。通常情况下,当你自定义一个实现了 LifecycleOwner 的类时,你会使用 LifecycleRegistry 来跟踪和报告生命周期状态的变化。

  • 用途:

    • 它允许你在自定义组件中精确地控制生命周期状态。
    • 可以用来创建具有生命周期感知能力的自定义视图或其他组件。

传统方式

传统方式一般是指 Java 语言,没有使用协程的情况下。

Fragment 中的使用

初始化生命周期相关逻辑
csharp 复制代码
public Fragment() {
    initLifecycle();
}

private void initLifecycle() {
    mLifecycleRegistry = new LifecycleRegistry(this);
    ...
}

LifecycleRegistry 是生命周期的实现者

Fragment 生命周期回调
scss 复制代码
//onCreate
void performCreate(Bundle savedInstanceState) {
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
    ...
}
//onStart
void performStart() {
    ...
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    if (mView != null) {
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }
}
//onResume
void performResume() {
    ...
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    if (mView != null) {
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    }
}
void performStop() {
    if (mView != null) {
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
    }
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
}
void performDestroy() {
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}
通过观察者生命周期变化

Fragment生命周期变化的时候,handleLifecycleEvent方法最后会通知所有的观察者

kotlin 复制代码
open fun handleLifecycleEvent(event: Event) {
    moveToState(event.targetState)
}
private fun moveToState(next: State) {
    ...
    sync()
    ...
}
//简单理解就是状态同步,生命周期同步变化,让观察者做出需要的改变
private fun sync() {
    ...
    while (!isSynced) {
        newEventOccurred = false
        if (state < observerMap.eldest()!!.value.state) {
            backwardPass(lifecycleOwner)
        }
        val newest = observerMap.newest()
        if (!newEventOccurred && newest != null && state > newest.value.state) {
            forwardPass(lifecycleOwner)
        }
    }
}

到这里我们已经简单介绍完了,当Fragment 生命周期变化的时候,如何通过 LifecycleOwnerLifecycleRegistry 通知观察者的

注册

通知观察者流程,但是应该还需要有一个注册流程,没有注册就拿不到观察者

前面讲过 LifecycleOwner 表示某个类拥有一个 Lifecycle ,而LifecycleRegistryLifecycle 的具体实现者。在 LifecycleRegistry 中,有一个注册方法,addObserver 主要是通过它来完成注册流程,当生命周期变化时候,就会把注册在LifecycleRegistry 中的所有观察者都通知一遍。后面我们会讲具体的使用场景。

存在两个生命周期的实现者

通过查看Fragment源代码可以看到,有两个关注生命周期的实现,mLifecycleRegistrymViewLifecycleOwner

  • fragment.lifecycle:表示 整个 Fragment 的生命周期
  • viewLifecycleOwner.lifecycle:表示 Fragment 中 View 的生命周期

两个 Lifecycle 的生命周期状态流程对比,区别主要在于 onCreateonDestroy 方法对于

viewLifecycleOwner 来说不回调

Fragment 方法 fragment.lifecycle 状态 viewLifecycleOwner.lifecycle 状态
onCreate() CREATED 不可用(View 尚未创建)
onCreateView() CREATED
onStart() STARTED STARTED
onResume() RESUMED RESUMED
onPause() STARTED STARTED
onStop() CREATED CREATED
onDestroyView() DESTROYED
onDestroy() DESTROYED 已经销毁

Activity 中的使用

Activity 中 ,一样是通过mLifecycleRegistry 来管理生命周期,也就是通过它把Activity 的生命周期,

应用到各个组件,比如ViewModel,让其他组件同样具备生命周期的能力

具备生命周期的组件

  • LiveData
arduino 复制代码
// 观察 LiveData
viewModel.username.observe(viewLifecycleOwner, Observer { username ->
    textView.text = "当前用户:$username"
})

在传统的方式,我们一般会这样使用 LiveData ,使用 viewLifecycleOwner

less 复制代码
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    ...
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    ...
    owner.getLifecycle().addObserver(wrapper);
}

最后还是调用了 owner.getLifecycle(),也就是真实的实现者,LifecycleRegistry,向它注册了观察者。

在我们每次向 LiveData 赋予新值的时候,会通知观察者

typescript 复制代码
protected void setValue(T value) {
    assertMainThread("setValue");
    mVersion++;
    mData = value;
    dispatchingValue(null);
}

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    ...   
    if (!observer.mActive) {
        return;
    }
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    considerNotify(initiator);
    ...
}
private void considerNotify(ObserverWrapper observer) {
    ...
    observer.mObserver.onChanged((T) mData);
}

observer.mActive 表示它是具备生命周期的,只有活跃的情况下,才会发送消息。

scss 复制代码
@Override
boolean shouldBeActive() {
    return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}

也就是宿主,如果已经不活跃了,消息就不会发送了。

LifecycleBoundObserver onStateChanged方法内部,会主动解除绑定关系currentState == DESTROYED

less 复制代码
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
        Lifecycle.@NonNull Event event) {
    Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
    if (currentState == DESTROYED) {
        removeObserver(mObserver);
        return;
    }
    Lifecycle.State prevState = null;
    while (prevState != currentState) {
        prevState = currentState;
        activeStateChanged(shouldBeActive());
        currentState = mOwner.getLifecycle().getCurrentState();
    }
}
相关推荐
用户693717500138444 分钟前
Kotlin 协程基础入门系列:从概念到实战
android·后端·kotlin
SHEN_ZIYUAN1 小时前
Android 主线程性能优化实战:从 90% 降至 13%
android·cpu优化
曹绍华1 小时前
android 线程loop
android·java·开发语言
雨白1 小时前
Hilt 入门指南:从 DI 原理到核心用法
android·android jetpack
介一安全1 小时前
【Frida Android】实战篇3:基于 OkHttp 库的 Hook 抓包
android·okhttp·网络安全·frida
sTone873751 小时前
Android Room部件协同使用
android·前端
我命由我123452 小时前
Android 开发 - Android JNI 开发关键要点
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
千码君20162 小时前
Android Emulator hypervisor driver is not installed on this machine
android
lichong9512 小时前
Android studio release 包打包配置 build.gradle
android·前端·ide·flutter·android studio·大前端·大前端++