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 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台1 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone1 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc1 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo1 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077001 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼1 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone1 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen1 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone1 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui