生命周期组件大揭秘:从Lifecycle到ViewModelScope,一篇文章让你秒懂!

226 阅读4分钟

生命周期组件大揭秘:从Lifecycle到ViewModelScope,一篇文章让你秒懂!

嘿,各位刚踏入Android开发江湖的小伙伴们,是不是经常被Lifecycle、LifecycleOwner、ViewLifecycleOwner、LifecycleScope、ViewModelScope这些“高大上”的名词搞得晕头转向?别怕,今天咱们就来一场“生命周期组件”的欢乐大探险,保证让你笑中带学,轻松掌握这些概念!

一、Lifecycle:生命周期的“超级侦探”

想象一下,你正在开发一个Activity,需要管理定位服务的开启和关闭。传统做法是在onStart里开启,onStop里关闭,但如果页面一多,每个页面都得重复写一遍,岂不是累成狗?更别提如果把这些逻辑塞进BaseActivity,那普通Activity岂不是要“哭晕在厕所”?

别怕,Lifecycle来救场了!它就像是一个超级侦探,能感知Activity的生命周期变化,并在对应时机触发组件里的方法。比如,你可以创建一个MyObserver,通过getLifecycle().addObserver添加到Activity中,这样Activity的生命周期变化就能被MyObserver“看”得一清二楚了!

示例代码

class MyObserver(
    private val context: Context,
    private val lifecycle: Lifecycle,
    private val callback: (Location) -> Unit
) : DefaultLifecycleObserver {
    override fun onResume(owner: LifecycleOwner) {
        if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
            // 开启定位服务
        }
    }

    override fun onPause(owner: LifecycleOwner) {
        // 关闭定位服务
    }
}

二、LifecycleOwner:生命周期的“大管家”

LifecycleOwner就像是一个大管家,它提供了getLifecycle()方法,让你能拿到Lifecycle对象,从而添加观察者。Activity和Fragment都实现了LifecycleOwner接口,所以它们都能轻松管理自己的生命周期。

如果你想自定义一个LifecycleOwner,比如让一个普通类也能感知生命周期,那就可以使用LifecycleRegistry类,并手动转发生命周期事件给它。

示例代码

class MyActivity : Activity(), LifecycleOwner {
    private lateinit var lifecycleRegistry: LifecycleRegistry

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lifecycleRegistry = LifecycleRegistry(this)
        lifecycleRegistry.markState(Lifecycle.State.CREATED)
    }

    override fun onStart() {
        super.onStart()
        lifecycleRegistry.markState(Lifecycle.State.STARTED)
    }

    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistry
    }
}

三、ViewLifecycleOwner:Fragment中View的“专属管家”

在Fragment里,LifecycleOwner是针对Fragment本身的,而ViewLifecycleOwner则是针对Fragment中View的“专属管家”。它会在onCreateView之前赋值,在onDestroyView之后置空。

为什么需要ViewLifecycleOwner呢?因为Fragment入back stack时,会执行onDestroyView但不执行onDestroy与onDetach,而出back stack时则从onCreateView开始执行。所以,Fragment中View的生命周期与Fragment本身并不相同,需要有一个专属的“管家”来管理。

四、LifecycleScope:协程的“生命周期守护者”

LifecycleScope,顾名思义,就是Lifecycle里的协程作用域。它能让协程代码在特定的生命周期执行,并在Lifecycle被销毁时自动取消协程。你可以通过lifecycle.coroutineScope或lifecycleOwner.lifecycleScope属性来访问它。

示例代码

lifecycleScope.launch { 
    withContext(Dispatchers.IO) {
        // 执行IO操作
    }
}

lifecycleScope.launchWhenResumed {
    // 当Activity/Fragment处于RESUMED状态时执行
}

五、repeatOnLifecycle & lifecycle.whenXxx:协程的“智能调度员”

  • lifecycle.launch:这个“调度员”比较“固执”,即使Activity/Fragment处于后台,也会一直执行协程代码,生产者也保持活跃。
  • repeatOnLifecycle:这个“调度员”比较“聪明”,它能在指定的生命周期执行协程代码,当不再处于该状态时就会取消协程块的执行。比如,当程序处于后台时,视图层收集停止,数据生产者也停止。
  • lifecycle.whenXxx:这个“调度员”则有点“懒”,它能在指定的生命周期执行协程代码,但当不再处于该状态时就会暂停协程块的执行。比如,当程序处于后台时,视图层收集暂停,但数据生产者仍然活跃,可能会持续发出不需要在屏幕上显示的数据项,从而占用内存。

示例对比

  • viewLifecycleOwner.lifecycleScope.launch{}:应用程序处于后台时不会停止。
  • lifecycleScope.launch {lifecycle.whenResumed {}}:应用程序处于后台时视图层收集暂停,生产者仍活跃,返回时从暂停处继续。
  • lifecycleScope.launch {viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {}}:应用程序处于后台时视图层收集停止,生产者停止,返回时从头开始。

六、ViewModelScope:ViewModel的“专属协程作用域”

最后,咱们来看看ViewModelScope。它就像是一个ViewModel的“专属协程作用域”,如果ViewModel被清除了,那么在此范围内启动的协程都会自动取消。这样,你就不必担心协程泄漏的问题了!

示例代码

implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'

// 在ViewModel中使用
class MyViewModel : ViewModel() {
    init {
        viewModelScope.launch {
            // 执行协程操作
        }
    }
}

好啦,今天的“生命周期组件”欢乐大探险就到这里啦!希望这篇文章能让你对这些概念有更清晰的认识,以后在开发中能更加游刃有余!