Jetpack Lifecycles 使用、原理解析

一、引言

在 Android 开发中,管理组件(如 Activity、Fragment)的生命周期是一项复杂且重要的任务。当组件的生命周期发生变化时,我们可能需要执行一些相应的操作,例如在组件销毁时释放资源,或者在组件启动时开始某些任务。Jetpack Lifecycles 库为开发者提供了一种便捷的方式来处理组件的生命周期,使得代码更加简洁、可维护,并且能够有效避免内存泄漏等问题。

二、Lifecycles 基本概念

2.1 Lifecycle

Lifecycle 是一个抽象类,它代表了一个组件(如 Activity 或 Fragment)的生命周期状态和事件。它包含两个主要的枚举类型:

  • Lifecycle.State:表示组件的当前生命周期状态,包括 INITIALIZEDCREATEDSTARTEDRESUMEDDESTROYED 等。
  • Lifecycle.Event:表示生命周期状态变化时触发的事件,如 ON_CREATEON_STARTON_RESUMEON_PAUSEON_STOPON_DESTROY 等。

2.2 LifecycleOwner

LifecycleOwner 是一个接口,任何实现了该接口的类都可以提供一个 Lifecycle 对象。在 Android 中,AppCompatActivityFragment 都已经实现了 LifecycleOwner 接口,因此它们可以直接提供自己的 Lifecycle 对象。

2.3 LifecycleObserver

LifecycleObserver 是一个接口,用于定义监听 Lifecycle 事件的观察者。通过在观察者类中定义带有特定注解的方法,可以在相应的生命周期事件发生时执行相应的操作。

三、Lifecycles 的基本使用

3.1 添加依赖

要使用 Lifecycles 库,需要在项目的 build.gradle 文件中添加以下依赖:

groovy 复制代码
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'

3.2 创建 LifecycleObserver

创建一个实现 LifecycleObserver 接口的类,并在类中定义带有特定注解的方法来处理生命周期事件。以下是一个简单的示例:

kotlin 复制代码
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent

class MyLifecycleObserver : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate() {
        // 在组件创建时执行的操作
        println("onCreate called")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onStart() {
        // 在组件启动时执行的操作
        println("onStart called")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume() {
        // 在组件恢复时执行的操作
        println("onResume called")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause() {
        // 在组件暂停时执行的操作
        println("onPause called")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onStop() {
        // 在组件停止时执行的操作
        println("onStop called")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy() {
        // 在组件销毁时执行的操作
        println("onDestroy called")
    }
}

3.3 在 Activity 或 Fragment 中使用 LifecycleObserver

在 Activity 或 Fragment 中获取 Lifecycle 对象,并将 LifecycleObserver 注册到该 Lifecycle 上。以下是在 Activity 中使用的示例:

kotlin 复制代码
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 创建 LifecycleObserver 实例
        val observer = MyLifecycleObserver()

        // 获取 Lifecycle 对象并注册观察者
        lifecycle.addObserver(observer)
    }
}

MainActivity 的生命周期发生变化时,MyLifecycleObserver 中的相应方法会被调用。

3.4 使用 Lifecycle 进行资源管理

Lifecycles 可以帮助我们更好地管理资源,例如在组件销毁时释放资源。以下是一个使用 Lifecycle 管理 MediaPlayer 资源的示例:

kotlin 复制代码
import android.content.Context
import android.media.MediaPlayer
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent

class MediaPlayerManager(private val context: Context, private val lifecycle: Lifecycle) : LifecycleObserver {

    private var mediaPlayer: MediaPlayer? = null

    init {
        // 注册观察者
        lifecycle.addObserver(this)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun startPlaying() {
        mediaPlayer = MediaPlayer.create(context, R.raw.sample_audio)
        mediaPlayer?.start()
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun stopPlaying() {
        mediaPlayer?.stop()
        mediaPlayer?.release()
        mediaPlayer = null
    }
}

MainActivity 中使用 MediaPlayerManager

kotlin 复制代码
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 创建 MediaPlayerManager 实例
        val mediaPlayerManager = MediaPlayerManager(this, lifecycle)
    }
}

这样,MediaPlayer 会在 Activity 启动时开始播放音频,并在 Activity 停止时释放资源,避免了资源泄漏。

四、Lifecycles 源码原理解析

4.1 LifecycleRegistry

LifecycleRegistryLifecycle 的具体实现类,它负责管理 Lifecycle 的状态和事件,并通知注册的观察者。以下是 LifecycleRegistry 的主要工作流程:

状态管理

LifecycleRegistry 内部使用一个 State 变量来表示当前的生命周期状态,并提供了方法来更新状态:

kotlin 复制代码
private State mState;

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    State next = getStateAfter(event);
    moveToState(next);
}

private void moveToState(State next) {
    if (mState == next) {
        return;
    }
    mState = next;
    if (mHandlingEvent || mAddingObserverCounter != 0) {
        mNewEventOccurred = true;
        // 等待当前事件处理完成或观察者添加完成后再处理新事件
        return;
    }
    mHandlingEvent = true;
    sync();
    mHandlingEvent = false;
}

handleLifecycleEvent() 方法用于处理生命周期事件,根据事件类型计算出下一个状态,并调用 moveToState() 方法更新状态。

观察者管理

LifecycleRegistry 内部使用一个 Map 来存储注册的观察者,并在状态变化时通知它们:

kotlin 复制代码
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
        new FastSafeIterableMap<>();

public void addObserver(@NonNull LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    if (previous != null) {
        return;
    }
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        // 避免在 LifecycleOwner 已经销毁时添加观察者
        return;
    }

    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {
        pushParentState(statefulObserver.mState);
        statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
        popParentState();
        // 确保状态更新正确
        targetState = calculateTargetState(observer);
    }

    if (!isReentrance) {
        // 同步状态
        sync();
    }
    mAddingObserverCounter--;
}

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;
        // 当前状态小于最新状态,需要向上同步
        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;
}

addObserver() 方法用于注册观察者,将观察者包装成 ObserverWithState 对象并存储在 mObserverMap 中。在状态变化时,sync() 方法会确保所有观察者的状态与当前 Lifecycle 的状态同步。

4.2 LifecycleEventObserver 和 ReflectiveGenericLifecycleObserver

LifecycleEventObserver 是一个接口,用于直接处理生命周期事件。而 ReflectiveGenericLifecycleObserver 是一个实现了 LifecycleEventObserver 接口的类,它通过反射机制调用观察者类中带有 @OnLifecycleEvent 注解的方法。

kotlin 复制代码
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
    private final Object mWrapped;
    private final CallbackInfo mInfo;

    ReflectiveGenericLifecycleObserver(Object wrapped) {
        mWrapped = wrapped;
        mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
        mInfo.invokeCallbacks(source, event, mWrapped);
    }
}

ReflectiveGenericLifecycleObserver 在构造函数中通过 ClassesInfoCache 获取观察者类的回调信息,并在 onStateChanged() 方法中调用相应的回调方法。

4.3 组件(Activity、Fragment)与 Lifecycle 的集成

在 Android 中,AppCompatActivityFragment 等组件已经集成了 Lifecycle。以 AppCompatActivity 为例,它在内部维护了一个 LifecycleRegistry 对象,并在生命周期方法中调用 LifecycleRegistryhandleLifecycleEvent() 方法来更新 Lifecycle 的状态:

kotlin 复制代码
public class AppCompatActivity extends FragmentActivity implements AppCompatCallback {
    private final LifecycleRegistry mFragmentLifecycleRegistry = new LifecycleRegistry(this);

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
    }

    @Override
    protected void onStart() {
        super.onStart();
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    }

    @Override
    protected void onPause() {
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
        super.onPause();
    }

    @Override
    protected void onStop() {
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
        super.onDestroy();
    }

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mFragmentLifecycleRegistry;
    }
}

这样,当 AppCompatActivity 的生命周期发生变化时,LifecycleRegistry 的状态也会相应更新,并通知注册的观察者。

五、总结

Jetpack Lifecycles 库为 Android 开发者提供了一种强大而便捷的方式来管理组件的生命周期。通过使用 LifecycleLifecycleOwnerLifecycleObserver,我们可以将生命周期相关的逻辑从组件中分离出来,使代码更加简洁、可维护。LifecycleRegistry 作为 Lifecycle 的具体实现,负责管理状态和事件,并通知观察者。在实际开发中,合理使用 Lifecycles 可以有效避免内存泄漏等问题,提高应用的稳定性和性能。

相关推荐
二流小码农1 小时前
鸿蒙开发:如何实现文本跑马灯效果
android·ios·harmonyos
二流小码农1 小时前
鸿蒙开发:单一手势实现长按事件
android·ios·harmonyos
二流小码农2 小时前
鸿蒙开发:信息标记组件
android·ios·harmonyos
利维亚的杰洛特2 小时前
【Android15 ShellTransitions】(九)结束动画+Android原生ANR问题分析
android
二流小码农3 小时前
鸿蒙开发:单一手势实现多次点击事件
android·ios·harmonyos
江上清风山间明月4 小时前
一周掌握Flutter开发--8. 调试与性能优化(下)
android·flutter·性能优化
Mr_万能胶5 小时前
要失业了!写在 Android “不再开源”之后
android·android studio·android jetpack
Renounce5 小时前
【Android】ViewModel和AndroidViewModel区别
android
珹洺6 小时前
Java-servlet(九)前端会话,会话管理与Cookie和HttpSession全解析
android·java·服务器·开发语言·前端·数据库·servlet
七郎的小院6 小时前
性能优化ANR系列之-Service ANR原理
android·客户端