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();
    }
}
相关推荐
Jackilina_Stone9 小时前
【faiss】用于高效相似性搜索和聚类的C++库 | 源码详解与编译安装
android·linux·c++·编译·faiss
棒棒AIT10 小时前
mac 苹果电脑 Intel 芯片(Mac X86) 安卓虚拟机 Android模拟器 的救命稻草(下载安装指南)
android·游戏·macos·安卓·mac
fishwheel10 小时前
Android:Reverse 实战 part 2 番外 IDA python
android·python·安全
消失的旧时光-194313 小时前
Android网络框架封装 ---> Retrofit + OkHttp + 协程 + LiveData + 断点续传 + 多线程下载 + 进度框交互
android·网络·retrofit
zcychong13 小时前
Handler(二):Java层源码分析
android
Chef_Chen15 小时前
从0开始学习R语言--Day58--竞争风险模型
android·开发语言·kotlin
用户20187928316716 小时前
演员的智能衣橱系统之Selector选择器
android
CYRUS_STUDIO16 小时前
OLLVM 混淆 + VMP 壳照样破!绕过加壳 SDK 的核心检测逻辑
android·逆向·汇编语言
Kapaseker16 小时前
憋了一周了,12000字深入浅出Android的Context机制
android