Lifecycles 即生命周期,属于 Jetpack 架构组件之一的 Lifecycles 组件是可以为其它组件提供生命周期感知能力的一个组件,而具备了生命周期感知能力的组件就叫生命周期感知组件,注意加粗部分多读两遍,我看网上很多文章直接把 Lifecycles 组件叫生命周期感知组件?
那么什么是生命周期感知能力呢?我们知道四大基础组件有生命周期,能感知这些生命周期的组件就具备了生命周期感知能力,所以我认为以前我们使用的 MVP 模式中的 Presenter 如果它通过接口等方式间接获得了 Activity 的生命周期,它也算是一个生命周期感知组件,但是这种获取生命周期的方式和 Lifecycles 比起来还是太 low 了,我们接着对比传统生命周期感知方式,聊一聊为什么使用 Lifecycles 组件
我们知道,一个 Android App 之所以能够完成一系列复杂任务,都是基于各个基础组件之间的密切配合,我们熟知的四大组件(Activity、Service、Broadcast、Content Provider)是有生命周期的,并且 Android 的操作系统层或者 FrameWork 框架层会为其提供相应的回调,以便程序在不同的状态下做相对正确的事;而普通的组件或者我们自己开发的一些组件就没有这个待遇了,我们通常需要在合适的时候,手动将这些第三方组件的状态控制方法,诸如启动/关闭/注册/拆除等,添加到具备生命周期的组件的回调中去才能使它们正确工作。
然后,随着时间推移版本迭代,引用的第三方组件越来越多,你的代码逐渐变成了这样
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()
...
}
你可能会在 Presenter 中完成这一系列操作,但这其实没有解决根本问题:随着第三方组件越来越多的引入,你的 Presenter 也越来越难以维护和测试。而且还可能出现内存泄露的情况
override fun onStart() {
Util.checkUserStatus { result ->
// 此回调可能在 onStop 之后被调用
if(result){
b.start()
}
}
}
...
override fun onStop(){
b.stop()
}
我们接着来看 Lifecycles 组件如何解决这些问题
Lifecycles 组件主要包含两个部分: Lifecycle 和 LifecycleOwner
Lifecycle 类包含有关组件生命周期状态的信息(如 Activity 或 Fragment),并允许其他对象观察此状态
Lifecycle 使用两个主要的枚举类型来跟踪与他相关的组件的生命周期状态:
Event 分发自 framework 和 Lifecycle 类,这些 Event 映射到 Activity 和 Fragment 中的回调事件
Lifecycle 对象跟踪的组件的当前状态
Event 和 State 的关系
你可以把 State 看作事件的节点,而 Event 就是这些节点之间的过程
类可以通过向其方法添加注释来监视组件的生命周期状态。然后通过调用 Lifecycle.addObserver()
方法并传递观察者的实例来添加观察者,如下所示:
class MyObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun connectListener() {
...
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun disconnectListener() {
...
}
}
myLifecycleOwner.getLifecycle().addObserver(MyObserver())
myLifecycleOwner 是一个实现了 LifecycleOwner 接口的对象,我们来看看 LifecycleOwner
LifecycleOwner 是一个单方法接口,表示该类具有生命周期,它只有一个抽象方法 abstract getLifecycle()
/**
* A class that has an Android lifecycle. These events can be used by custom components to
* handle lifecycle changes without implementing any code inside the Activity or the Fragment.
*
* @see Lifecycle
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
@NonNull
Lifecycle getLifecycle();
}
此接口从各个类中( AppCompatActivity / Fragment 等)抽象出生命周期所有权,并允许任何自定义应用程序类都可以实现 LifecycleOwner 接口
我们通过一个简易计时器的例子来进行调整,在 Android Jetpack - ViewModel 中,我们实现了一个简易计时器,该计时器可以在 Activity 处于配置更改或后台的情况下继续计时,我们现在利用 Lifecycle 修改它,让它只能在 Activity 处于可见状态的情况下计时
这一步很简单也很重要,只有通过 LifecycleObserver 标记的类才能被 LifecycleOwner 添加并观察
class TimerViewModel : ViewModel(),LifecycleObserver{
...
}
在 ViewModel 中添加 start()
和 stop()
...
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun start(){
startTime = SystemClock.elapsedRealtime() - stopTime
// 让 UI 立即更新最新结果
_elapsedTime.postValue((SystemClock.elapsedRealtime() - startTime!!)/1000)
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun stop(){
stopTime = elapsedMilliseconds
}
...
class MainActivity : AppCompatActivity() {
private val viewModel by lazy {
ViewModelProviders.of(this).get(TimerViewModel::class.java)
}
@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel.elapsedTime.observe(this, Observer {
tv_time.text = "$it second elapsed"
})
// 添加观察者
lifecycle.addObserver(viewModel)
}
注意这里的 MainActivity 继承自 AppCompatActivity,由于 AppCompatActivity 继承自 ComponentActivity,而 ComponentActivity 实现了 LifecycleOwner,所以不需要手动注册 MainActivity 为 LifecycleOwner,直接调用 getLifecycle()
即可
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
LifecycleOwner,
ViewModelStoreOwner,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner {
...
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
...
}
现在,ViewModel 带有 @OnLifecycleEvent(Lifecycle.Event.ON_START)
注解的函数就会在 MainActivity onStart
时被调用,onStop
同理,这样我们就实现了后台暂停计时的效果
https://github.com/realskyrin/jetpack_lifecycles
https://developer.android.com/topic/libraries/architecture/lifecycle
https://developer.android.com/reference/androidx/lifecycle/Lifecycle.html
https://developer.android.com/reference/androidx/lifecycle/LifecycleOwner.html