Android Jetpack - Lifecycle

160 阅读3分钟

生命周期感知型组件可执行操作来响应另一个组件(如 Activity 和 Fragment)的生命周期状态的变化。androidx.lifecycle 软件包提供了可用于构建生命周期感知型组件的类和接口,这些组件可以根据 Activity 或 Fragment 的当前生命周期状态自动调整其行为。

Lifecycle

用于存储有关组件(如 Activity 或 Fragment)的生命周期状态的信息,并允许其他对象观察此状态。 Lifecycle 使用两种主要枚举跟踪其关联组件的生命周期状态:

  • 事件:从框架和 Lifecycle 类分派的生命周期事件
  • 状态:由 Lifecycle 对象跟踪的组件的当前状态

在这里插入图片描述

我们可以通过实现 DefaultLifecycleObserver 并替换相应的方法来监控组件的生命周期状态,然后调用 Lifecycle 类的 addObserver 方法并传递观察器的实例来添加观察器。

class MyLifecycleObserver : DefaultLifecycleObserver {

    private val tag = "MyLifecycleObserver"

    override fun onCreate(owner: LifecycleOwner) {
        super.onCreate(owner)
        Log.i(tag, "onCreate")
    }

    override fun onDestroy(owner: LifecycleOwner) {
        super.onDestroy(owner)
        Log.i(tag, "onDestroy")
    }
}
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding =
            DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        lifecycle.addObserver(MyLifecycleObserver())
    }

}

LifecycleOwner 是单一方法接口,表示类具有 Lifecycle,实现 DefaultLifecycleObserver 的组件可与实现 LifecycleOwner 的组件完美配合,因为所有者可以提供生命周期,而观察者可以注册以观察生命周期,Fragment 和 Activity 已经实现了 LifecycleOwner 接口。

我们也可以查询当前状态,例如

        if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
            //todo
        }

ViewModel

ViewModel 是一种业务逻辑或屏幕级状态容器,它用于将状态公开给界面,以及封装相关的业务逻辑。 它可以缓存状态,并可在配置更改后持久保留相应状态,这就意味着在 Activity 之间导航时或进行配置更改后(例如旋转屏幕时),界面无需重新提取数据。

在这里插入图片描述

ViewModel 的生命周期从 Activity 首次创建(onCreate)开始,直到 Activity 真正销毁(onDestroy)且不再重建时才会销毁。ViewModel 的生命周期与 Activity 的 ViewModelStore 相关联,只要 Activity 的 ViewModelStore 存在,ViewModel 就会存在,屏幕旋转时,Activity 的 ViewModelStore 会被保留,因此 ViewModel 不会被销毁。

LiveData

LiveData 是一种具有生命周期感知能力的可观察的数据存储器类,它遵循其他应用组件(如 activity,fragment 或 service)的生命周期。如果观察者的生命周期处于 STARTED 或 RESUMED 状态,则 LiveData 会认为该观察者处于活跃状态,LiveData 只会将更新通知给活跃的观察者,非活跃观察者不会收到更改通知。

这对于 activity 和 fragment 特别有用,可以放心地观察 LiveData 对象,不必担心泄露,因为当 activity 和 fragment 的生命周期被销毁时,系统会立即退订它们。

这里通过一个简单的示例,来说明 ViewModel 和 LiveData 的使用。

implementation "androidx.activity:activity-ktx:1.5.1"
class MainViewModel : ViewModel() {
    val showText = MutableLiveData<String>()
}
<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

        <variable
            name="showText"
            type="String" />

        <variable
            name="click"
            type="com.example.myapplication.MainActivity.ClickEventListener" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        tools:context=".MainActivity">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{click::changeText}"
            android:text="change"
            android:textAllCaps="false" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{showText}" />

    </LinearLayout>
</layout>
class MainActivity : AppCompatActivity() {

    private val mainViewModel by viewModels<MainViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding =
            DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        with(binding) {
            showText = "Original Content"
            click = ClickEventListener()
        }
        mainViewModel.showText.observe(this) {
            binding.showText = it
        }
    }

    inner class ClickEventListener {
        fun changeText(view: View) {
            mainViewModel.showText.value = "Content After Change"
        }
    }

}