简介
Lifecycle是Jetpack中提供的一个用于感知生命周期的组件,在应用中主要用于监听 Activity和Fragment的生命周期变化,在合适的时候释放资源,防止内存泄露。使用Lifecycle可以将依赖组件的代码从生命周期方法移入组件本身中。避免了直接在Activity或Fragment的生命周期方法中操作组件。比如,我们常用的方式如下:
class MyActivity:AppCompatActivity() {
override fun onStart() {
super.onStart()
LocationUtils.start()
}
override fun onStop() {
super.onStop()
LocationUtils.stop()
}
}
如果多个页面都用到了这个工具类,就需要写多遍,如果多人开发,并不能保证一定都会调用对应的方法,这样难以维护。
androidx.lifecycle
软件包提供了可用于构建生命周期感知组件的类和接口,这些组件可以根据Activity
或 Fragment
的当前生命周期状态自动调整其行为。
在 Android 框架中定义的大多数应用组件都存在生命周期。生命周期由操作系统或进程中运行的框架代码管理。它们是 Android 工作原理的核心,应用必须遵循它们。如果不这样做,可能会引发内存泄漏甚至应用崩溃。
相关类和接口
Lifecycle
Lifecycle
本身是一个抽象类,用于存储有关组件(如 Activity 或 Fragment)的生命周期状态的信息,并允许其他对象观察此状态。它主要通过两个枚举类:Event
和State
来关联组件的生命周期。
Event : 从框架和
Lifecycle
类分派的生命周期事件。这些事件映射到 Activity 和 Fragment 中的回调事件。
State : 由Lifecycle
对象跟踪的组件的当前状态。
![](https://img.haomeiwen.com/i1797490/cae5b5e50e35ea6d.png)
LifecycleOwner
LifecycleOwner
是单一方法接口,表示类具有 Lifecycle
。它具有一种方法(即 getLifecycle()
),该方法必须由类实现,表示生命周期拥有者,提供者,属于被观察的对象。
LifecycleObserver
LifecycleObserver是一个标记接口,任何类都可以通过实现该接口来感知组件生命周期的变化,属于观察对象。
public interface LifecycleObserver {
}
实现LifecycleObserver
的组件可与实现LifecycleOwner
的组件无缝协同工作,因为生命周期所有者可以提供生命周期,而观察者可以注册以观察生命周期。
简单示例
我们现在有个需求,实现简单的计时功能,在打开应用时开始计时,Home键切换至后台则暂停计时,回到应用则继续之前的时间计时。首先,我们还是使用系统自带的Chronometer控件,代码如下:
class LifecycleTestActivity : AppCompatActivity() {
private lateinit var chronometer: Chronometer
private var elapsedTime: Long = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lifecycle_test)
chronometer = findViewById(R.id.chronometer)
chronometer.base = SystemClock.elapsedRealtime()
}
override fun onPause() {
super.onPause()
elapsedTime = SystemClock.elapsedRealtime() - chronometer.base
chronometer.stop()
}
override fun onResume() {
super.onResume()
chronometer.base = SystemClock.elapsedRealtime() - elapsedTime
chronometer.start()
}
}
我们通过在Activity的 onPause()
和onResume()
方法计算elapsedTime
该变量的值,并将其设置为Chronometer的base属性。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".lifecycle.LifecycleTestActivity">
<Chronometer
android:id="@+id/chronometer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22sp"
android:textColor="@color/purple_200"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
这个是我们以往的做法,存在代码移植复杂困难,在Activity的回调函数中忘记处理,代码冗余等问题。有了Lifecycle之后,我们的写法如下:
class MyChronometer @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : Chronometer(context, attrs, defStyleAttr), LifecycleObserver {
private var elapsedTime: Long = 0
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
private fun pauseMeter() {
elapsedTime = SystemClock.elapsedRealtime() - base
stop()
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
private fun resumeMeter() {
base = SystemClock.elapsedRealtime() - elapsedTime
start()
}
}
自定义控件继续系统Chronometer并实现LifecycleObserver
接口,并在pauseMeter()和resumeMeter()上添加 @OnLifecycleEvent
注解。
class LifecycleTestActivity : AppCompatActivity() {
private lateinit var chronometer: MyChronometer
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lifecycle_test)
chronometer = findViewById(R.id.chronometer)
//添加观察者
lifecycle.addObserver(chronometer)
}
}
网友评论