在编写Android应用程序的时候,可能会经常遇到需要感知Activity生命周期的情况。比如说,某个界面中发起了一条网络请求,但是当请求得到响应的时候,界面或许已经关闭了,这个时候就不应该继续对响应的结果进行处理。因此,需要能够时刻感知到Activity的生命周期,以便在适当的时候进行相应的逻辑控制。
在一个Activity中去感知它的生命周期非常简单,而如果要在一个非Activity的类中去感知Activity的生命周期,应该怎么办呢?
这种需求是广泛存在的,同时也衍生出了一系列的解决方案,比如通过在Activity中嵌入一个隐藏的Fragment来进行感知,或者通过手写监听器的方式来进行感知,等等。
下面的代码演示了如何通过手写监听器的方式来对Activity的生命周期进行感知:
class MainActivity : AppCompatActivity() {
lateinit var observer: MyObserver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
observer = MyObserver()
}
override fun onStart() {
super.onStart()
observer.activityStart()
}
override fun onStop() {
super.onStop()
observer.activityStop()
}
}
class MyObserver {
fun activityStart() {
}
fun activityStop() {
}
}
可以看到,为了让MyObserver能够感知到Activity的生命周期,需要专门在MainActivity中重写相应的生命周期方法,然后再通知给MyObserver。这种实现方式虽然是可以正常工作的,但是不够优雅,需要在Activity中编写太多额外的逻辑。
Lifecycles组件就是为了解决这个问题而出现的,它可以让任何一个类都能轻松感知Activity的生命周期,同时又不需要在Activity中编写大量的逻辑处理。
下面就通过具体的例子来学习Lifecycles组件的用法。新建一个MyObserver类,并让它实现LifecycleObserver接口,代码如下所示:
class MyObserver : LifecycleObserver {
}
LifecycleObserver是一个空方法接口,只需要进行一下接口实现声明就可以了,而不去重写任何方法。
接下来可以在MyObserver中定义任何方法,但是如果想要感知到Activity的生命周期,还得借助额外的注解功能才行。比如这里还是定义activityStart()和activityStop()这两个方法,代码如下所示:
class MyObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun activityStart() {
Log.e("MyObserver", "activityStart")
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun activityStop() {
Log.e("MyObserver", "activityStop")
}
}
在方法上使用了@OnLifecycleEvent注解,并传入了一种生命周期事件。生命周期事件的类型一共有7种:ON_CREATE、ON_START、ON_RESUME、ON_PAUSE、 ON_STOP和ON_DESTROY分别匹配Activity中相应的生命周期回调;另外还有一种ON_ANY类型,表示可以匹配Activity的任何生命周期回调。 因此,上述代码中的activityStart()和activityStop()方法就应该分别在Activity的onStart()和onStop()触发的时候执行。
但是代码写到这里还是无法正常工作的,因为当Activity的生命周期发生变化的时候并没有人去通知MyObserver,而我们又不想像刚才一样在Activity中去一个个手动通知。这个时候就得借助LifecycleOwner了,它可以使用如下的语法结构让MyObserver得到通知:
lifecycleOwner.lifecycle.addObserver(MyObserver())
首先调用LifecycleOwner的getLifecycle()方法,得到一个Lifecycle对象,然后调用它的addObserver()方法来观察LifecycleOwner的生命周期,再把MyObserver的实例传进去就可以了。
那么接下来的问题就是,LifecycleOwner又是什么呢?怎样才能获取一个LifecycleOwner的实例?
当然,也可以自己去实现一个LifecycleOwner,但通常情况下这是完全没有必要的。因为只要Activity是继承自AppCompatActivity的,或者Fragment是继承自androidx.fragment.app.Fragment的,那么它们本身就是一个LifecycleOwner的实例, 这部分工作已经由AndroidX库自动完成了。 以下是源码:
public class AppCompatActivity extends FragmentActivity implements AppCompatCallback,
TaskStackBuilder.SupportParentable, ActionBarDrawerToggle.DelegateProvider { }
public class FragmentActivity extends ComponentActivity implements
ActivityCompat.OnRequestPermissionsResultCallback,
ActivityCompat.RequestPermissionsRequestCodevalidator { }
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
LifecycleOwner,
ViewModelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOwner,
onBackPressedDispatcherOwner { }
也就是说,在MainActivity当中就可以这样写:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
lifecycle.addObserver(MyObserver())
}
}
只要添加这样一行代码,MyObserver就能自动感知到Activity的生命周期了。另外,需要说明的是,尽管一直在以Activity举例,但其实上述的所有内容在Fragment中也是通用 的。
现在重新运行一下程序,activityStart这条日志就会打印出来了。如果你再按下Home键或者Back键的话,activityStop这条日志也会打印出来。
这些就是Lifecycles组件最常见的用法了。不过目前MyObserver虽然能够感知到Activity的生命周期发生了变化,却没有办法主动获知当前的生命周期状态。要解决这个问题也不难,只需要在MyObserver的构造函数中将Lifecycle对象传进来即可, 如下所示:
class MyObserver(val lifecycle: Lifecycle) : LifecycleObserver {
.....
}
有了Lifecycle对象之后,就可以在任何地方调用lifecycle.currentState来主动获知当前的生命周期状态。lifecycle.currentState返回的生命周期状态是一个枚举类型, 一共有INITIALIZED、DESTROYED、CREATED、STARTED、RESUMED这5种状态类型,它们与Activity的生命周期回调所对应的关系如图所示:
也就是说,当获取的生命周期状态是CREATED的时候,说明onCreate()方法已经执行了,但是onStart()方法还没有执行。当获取的生命周期状态是STARTED的时候,说明onStart()方法已经执行了,但是onResume()方法还没有执行,以此类推。



