通过本文您将会了解到 Lifecycle.repeatOnLifecycle API 背后的设计决策,以及为什么我们会移除此前添加到 lifecycle-runtime-ktx 库 2.4.0 版本首个 alpha 版中的几个辅助函数。
纵观全文,您将了解到在某些场景中使用特定协程 API 的危险程度、为 API 命名的困难程度以及我们决定在函数库中只保留底层挂起 API 的原因。
同时,您会意识到所有的 API 决策都需要根据 API 的复杂度、可读性和容易出错程度进行权衡。
这里特别向 Adam Powel、Wojtek Kaliciński、Ian Lake 和 Yigit Boyar 致谢,感谢大家对 API 的反馈和讨论。
注意: 如果您在查找
repeatOnLifecycle
的使用指南,请查阅: 使用更为安全的方式收集 Android UI 数据流。
repeatOnLifecycle
Lifecycle.repeatOnLifecycle
API 最早是为了实现从 Android UI 层更安全地收集数据流而设计的。它的可重启行为充分考虑了 UI 生命周期,使其成为仅当 UI 在屏幕上处于可见时处理数据的最佳默认 API。
注意: LifecycleOwner.repeatOnLifecycle 也是可用的。它将此功能委托给其 Lifecycle 对象来实现。借此,所有已经属于 LifecycleOwner 作用域的代码都可以省略显式的接收器。
repeatOnLifecycle
是一个挂起函数 。就其本身而言,它需要在协程中执行。repeatOnLifecycle会将调用的协程挂起,然后每当生命周期进入 (或高于) 目标状态时在一个新的协程中执行您作为参数传入的一个挂起块。如果生命周期低于目标状态,因执行该代码块而启动的协程就会被取消。最后,repeatOnLifecycle 函数直到在生命周期处于 DESTROYED 状态时才会继续调用者的协程。
让我们在实例中了解这个 API 吧。如果您已经阅读过我此前的文章: 一种更安全的从 Android UI 当中获取数据流的方式 ,那您将不会对以下内容感到新奇。
class LocationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 由于 repeatOnLifecycle 是一个挂起函数,
// 因此从 lifecycleScope 中创建新的协程
lifecycleScope.launch {
// 直到 lifecycle 进入 DESTROYED 状态前都将当前协程挂起。
// repeatOnLifecycle 每当生命周期处于 STARTED 或以后的状态时会在新的协程中
// 启动执行代码块,并在生命周期进入 STOPPED 时取消协程。
repeatOnLifecycle(Lifecycle.State.STARTED) {
// 当生命周期处于 STARTED 时安全地从 locations 中获取数据
// 当生命周期进入 STOPPED 时停止收集数据
someLocationProvider.locations.collect {
// 新的位置!更新地图(信息)
}
}
// 注意:运行到此处时,生命周期已经处于 DESTROYED 状态!
}
}
}
注意 : 如果您对 repeatOnLifecycle 的实现方式感兴趣&#