Android Lifecycle代码分析:为什么使用;注解的方式为什么过期?源码分析;状态与事件

目录

  1. 为什么使用Lifecycle?为什么不直接使用原生的activity的生命周期呢?
  2. Lifecycle是什么?
  3. 使用Lifecycle
  4. Lifecycle源码分析

一、为什么使用Lifecycle?为什么不直接使用原生的activity的生命周期呢?

我们想象一种场景,假如说你读取数据,开启了一个任务,那么结束的要关掉,那么就要写到onStop里面,但如果一个页面的任务多了,结束的代码都写到了onStop里面,那么就会冗余,一大堆的结束任务。并且移植性差,组件移植的话,还要去各个地方去复制,一不小心就漏了。

kotlin 复制代码
override fun onStart() {
    a.init()
    b.start()
    c.initialize()
    ...
}
...
override fun onStop(){
    if(a!=null) a.remove()
    if(b!=null&&b.c!=null) {
        b.c.tearDown()
        b.stop()
    } 
    c.stop()
    ...
}

总结:

  • onCreate() 里启动网络请求,但页面关闭时未取消请求 → ​内存泄漏​
  • onStop() 后更新 UI → ​崩溃​
  • 手动在多个生命周期方法中写重复逻辑 → ​代码冗余​

二、 Lifecycle是什么?

为了简化生命周期管理,Android Jetpack 提供了 Lifecycle ,帮助开发者以更解耦的方式处理生命周期相关的逻辑。

  • 核心概念
    • LifecycleOwner:具有生命周期的组件(如 Activity/Fragment 实现了此接口)。
    • LifecycleObserver:观察 LifecycleOwner 的状态变化,并执行相应操作。
  • 使用场景
    • 自动释放资源(如停止网络请求、注销监听器)。帮助开发者管理资源、避免内存泄漏,并确保应用的行为符合预期。
    • 避免在后台执行不必要的任务(如更新 UI)。

三、使用

Android X已经帮助我们实现了这个接口LifecycleOwner。在AppcomActivity里面已经实现了监听。所以我们只需要实现观察者。

3.1 注解的方式

kotlin 复制代码
class MyLifecycleObserver : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun connectToNetwork() {
        // 当 LifecycleOwner(如 Activity)进入前台时执行
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun disconnectFromNetwork() {
        // 当 LifecycleOwner 进入后台时执行
    }
}

// 在 Activity/Fragment 中注册观察者
lifecycle.addObserver(MyLifecycleObserver())

执行逻辑:

  1. ​Activity 启动​​:

    • 执行 onCreate()onStart()onResume()
    • onResume() 被调用时,LifecycleRegistry 检测到 ON_RESUME 事件,触发观察者的 connectToNetwork()
  2. ​Activity 进入后台​​:

    • 用户按 Home 键 → 触发 onPause()
    • LifecycleRegistry 检测到 ON_PAUSE 事件,调用 disconnectFromNetwork()
  3. ​Activity 销毁​​:

    • 调用 onDestroy() 时,LifecycleRegistry 自动移除观察者,避免内存泄漏。

但,注解都已经过时了。

废弃原因​​:

  1. ​反射性能差​:注解需要运行时解析,影响效率
  2. ​代码可读性低​:无法直接看出生命周期关联关系
  3. ​编译期无校验​:拼写错误或错误注解只在运行时崩溃

替代方案,上面也说了,实现 LifecycleEventObserver DefaultLifecycleObserver,接下来,我们看看DefaultLifecycleObserver

3.2 DefaultLifecycleObserver

java 复制代码
class MyObserver implements DefaultLifecycleObserver {
    @Override
    public void onStart(@NonNull LifecycleOwner owner) { 
        // 明确关联到 onStart 生命周期
    }
}

​优势​​:

  • ​直接实现接口方法​:无反射,性能更高
  • ​编译期检查​:方法名错误会直接报错
  • ​代码更直观​:IDE 自动提示关联的生命周期

四、源码分析

4.1 涉及的接口

java 复制代码
LifecycleObserver接口
1. 注解:@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
csharp 复制代码
LifecycleOwner接口
1. 方法:Lifecycle getLifecycle();
markdown 复制代码
Lifecycle抽象类
1. 方法:addObserver

4.2 从addObserver方法开始进入:为什么会他会调用我们实现了LifecycleObserver,加了注解的方法呢?

java 复制代码
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }
        //进入主线流程
        lifecycle.addObserver(object : LifecycleObserver {

        })
    }
}
java 复制代码
@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);

把LifecycleObserver 传递进来以后要做什么,没错,要做反射,反射,才能拿到里面的方法,可以看到,他都取出了getClass。

java 复制代码
@Deprecated
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
    private final Object mWrapped;
    private final androidx.lifecycle.ClassesInfoCache.CallbackInfo mInfo;

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

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

Object wrapped就是我们的LifecycleObserver,

ini 复制代码
CallbackInfo getInfo(Class<?> klass) {
    CallbackInfo existing = mCallbackMap.get(klass);
    if (existing != null) {
        return existing;
    }
    existing = createInfo(klass, null);
    return existing;
}

使用map进行缓存。大部分的系统源码,都会搞缓存。第一次创建使用反射,第二次直接从缓存里面取。只要是反射都会搞缓存。避免消耗性能

4.3 LifecycleOwner的状态和事件

这里我们带着一个问题往下看看:为什么activity执行onstart会调用我们的方法,他是如何实现的呢?

java 复制代码
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        ContextAware,
        LifecycleOwner,
        .....

@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    // Restore the Saved State first so that it is available to
    // OnContextAvailableListener instances
    mSavedStateRegistryController.performRestore(savedInstanceState);
    mContextAwareHelper.dispatchOnContextAvailable(this);
    super.onCreate(savedInstanceState);
    ReportFragment.injectIfNeededIn(this);
    if (BuildCompat.isAtLeastT()) {
        mOnBackPressedDispatcher.setOnBackInvokedDispatcher(
                Api33Impl.getOnBackInvokedDispatcher(this)
        );
    }
    if (mContentLayoutId != 0) {
        setContentView(mContentLayoutId);
    }
}

我们看看ReportFragment.injectIfNeededIn(this)方法

Java 复制代码
@JvmStatic
fun injectIfNeededIn(activity: Activity) {
    if (Build.VERSION.SDK_INT >= 29) {
        // On API 29+, we can register for the correct Lifecycle callbacks directly
        LifecycleCallbacks.registerIn(activity)
    }
    // Prior to API 29 and to maintain compatibility with older versions of
    // ProcessLifecycleOwner (which may not be updated when lifecycle-runtime is updated and
    // need to support activities that don't extend from FragmentActivity from support lib),
    // use a framework fragment to get the correct timing of Lifecycle events
    val manager = activity.fragmentManager
    if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
        manager.beginTransaction().add(ReportFragment(), REPORT_FRAGMENT_TAG).commit()
        // Hopefully, we are the first to make a transaction.
        manager.executePendingTransactions()
    }
}

我们发现这里,为什么会有一个Fragment呢?因为我们都知道Activity执行生命周期的时候,如果Activity中有Fragment,那么Fragment也会执行相应的生命周期,所以他就这样来执行生命周期的。

我们来看看ReportFragment类的生命周期方法,果然会有

kotlin 复制代码
override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    dispatchCreate(processListener)
    dispatch(Lifecycle.Event.ON_CREATE)
}

override fun onStart() {
    super.onStart()
    dispatchStart(processListener)
    dispatch(Lifecycle.Event.ON_START)
}

我们看看dispatch方法

less 复制代码
@Deprecated
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
    private final Object mWrapped;
    private final androidx.lifecycle.ClassesInfoCache.CallbackInfo mInfo;

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

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

可以看到,最终,他取出反射对象,进行调用方法

csharp 复制代码
void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) {
    try {
        switch (mCallType) {
            case CALL_TYPE_NO_ARG:
                mMethod.invoke(target);
                break;
            case CALL_TYPE_PROVIDER:
                mMethod.invoke(target, source);
                break;
            case CALL_TYPE_PROVIDER_WITH_EVENT:
                mMethod.invoke(target, source, event);
                break;
        }
    } catch (InvocationTargetException e) {
        throw new RuntimeException("Failed to call observer method", e.getCause());
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }
}

而且是循环遍历所有的观察的,因为我们可以添加多个观察者。

scss 复制代码
while (statefulObserver.state < targetState && observerMap.contains(observer)
) {
    pushParentState(statefulObserver.state)
    val event = Event.upFrom(statefulObserver.state)
        ?: throw IllegalStateException("no event up from ${statefulObserver.state}")
    statefulObserver.dispatchEvent(lifecycleOwner, event)
    popParentState()
    // mState / subling may have been changed recalculate
    targetState = calculateTargetState(observer)
}

但前面我们会看到,有一个Lifecycle.Event.ON_CREATE,这是一个事件,前面我们用来注解的表标识,我们进去里面看,为什么会有一个State呢?有什么作用?

kotlin 复制代码
public val targetState: State
    get() {
        when (this) {
            ON_CREATE, ON_STOP -> return State.CREATED
            ON_START, ON_PAUSE -> return State.STARTED
            ON_RESUME -> return State.RESUMED
            ON_DESTROY -> return State.DESTROYED
            ON_ANY -> {}
        }
        throw IllegalArgumentException("$this has no target state")
    }

4.4 状态机(State)与事件(Event)是什么?

  1. 状态(State) :表示组件当前的生命周期阶段,例如:
    • INITIALIZED:刚初始化,未创建
    • CREATED:已创建(如Activity的onCreate执行后)
    • STARTED:已启动(如Activity的onStart执行后)
    • RESUMED:已恢复(如Activity的onResume执行后)
    • DESTROYED:已销毁
  1. 事件(Event) :触发状态变化的操作,例如:
    • ON_CREATE:对应onCreate()方法
    • ON_START:对应onStart()
    • ON_RESUME:对应onResume()
    • ON_PAUSE:对应onPause()
    • ON_STOP:对应onStop()
    • ON_DESTROY:对应onDestroy()

为什么会出现两个事件,对应一个状态呢?

  • 如果只用事件,当你想知道"当前是否在前台",只能通过记住最后一个事件(如 ON_RESUMEON_PAUSE)来推断。
  • 而状态(如 RESUMED)直接告诉你"当前在前台",无需记忆历史事件。

当你知道是前台,还是后台,如果是后台,有些任务就不要执行,这样就可以减少资源消耗了。

相关推荐
每次的天空40 分钟前
Android学习总结之Java篇(一)
android·java·学习
8931519602 小时前
Android开发Glide做毛玻璃效果
android·glide·android开发·android教程·glide做毛玻璃效果
whysqwhw2 小时前
DRouter代码走读
android
人生游戏牛马NPC1号3 小时前
学习Android(五)玩安卓项目实战
android·kotlin
和煦的春风5 小时前
案例分析 | SurfaceFlinger 大片Runnable引起的卡顿
android·linux
浩宇软件开发5 小时前
Android开发,实现一个简约又好看的登录页
android·java·android studio·android开发
未扬帆的小船6 小时前
在gpt的帮助下安装chales的证书,用于https在root情况下抓包
android·charles
万户猴6 小时前
【 Android蓝牙-十】Android各版本蓝牙行为变化与兼容性指南
android·蓝牙
张风捷特烈7 小时前
FFmpeg 7.1.1 | 调试 ffmpeg.c 环境 - Widows&Clion&WSL
android·ffmpeg