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();
    }
}
相关推荐
Go-higher11 分钟前
DriverTest 驾考知识卡片学习助手 —— 一款基于 Jetpack Compose 的现代 Android 学习APP
android·学习
安卓修改大师18 分钟前
安卓修改大师APK控件修改实战教程
android
阿pin35 分钟前
Android随笔-Zygote是什么?
android·zygote
小虎牙00737 分钟前
Android kotlin图片库Coil源码详解
android·前端
AFinalStone1 小时前
Android 7系统网络(一)全景图与调用链路概览
android·网络·frameworks
用户86022504674722 小时前
Android DEX 内存 Dump 全流程实战:从 APK 提取到无特征内存盲扫
android
杉氧5 小时前
兼容与共生:如何在旧项目中优雅地引入 Compose?
android·架构·android jetpack
Flynt6 小时前
Room 3.0 包名重构 + KMP 迁移:我把项目升级踩了个遍
android·数据库·kotlin
杉氧6 小时前
性能优化实战:如何定位冗余重组并榨干 Compose 的每一帧性能?
android·架构·android jetpack
阿pin7 小时前
Android随笔-ATMS与AMS区别与联系
android·ams·atms