概述
嘿,各位刚踏入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 {
// 执行协程操作
}
}
}