因为launchWhenStarted和repeatOnLifecycle(STARTED)提供了完全不同的功能(launchWhenStarted暂停协程的执行,repeatOnLifecycle 取消并重新启动新的协程),如果新API的名称相似(例如,使用launchWhen重新启动API),开发人员可能会感到困惑,甚至在没有注意到的情况下互换使用它们。
源
对于何时使用哪个更简单的解释是什么?
launchWhenStarted
只是一次性延迟。
repeatOnLifecycle
创建一个挂起点,该挂起点充当处理程序,该处理程序在生命周期进入提供状态时运行提供的块,并在生命周期低于它时取消它(因此STARTED
当它停止时会发生)。
更新:
请注意,launchWhenStarted
API 现已弃用,因为它可能会导致工作挂起很长时间。
目前,对于一次性一次性延迟,建议lifecycleScope.launch()
新作业,并在其中使用withStarted{ }
方法导致挂起,直到达到启动状态。
弃用和替换的详细说明在此谷歌跟踪器问题中。
repeatOnLifecycle
每次重复时从头开始重新启动其协程,并在每次生命周期低于指定状态时取消它。它非常适合收集大多数流,因为它会在不需要时完全取消流,从而节省与流继续发出值相关的资源。
launchWhenX
不会取消协程并重新启动它。它只是在启动时推迟,并在低于指定状态时暂停执行。他们计划弃用这些功能,但我怀疑如果他们这样做,则需要一些替换,因为您正在调用一些耗时的挂起函数,然后在完成后想要做一些事情,例如启动片段事务。为此使用repeatOnLifecycle
将导致重做耗时的操作。
由channel
支持的冷流或使用具有缓冲区(如buffer
、conflate
、flowOn
或shareIn
)的运算符进行收集是不安全的,使用某些现有 API(如CoroutineScope.launch
、Flow<T>.launchIn
或LifecycleCoroutineScope.launchWhenX
)进行收集,除非您手动取消在活动进入后台时启动协程的Job
。这些 API 将使底层流创建器保持活动状态,同时将项目发送到后台的缓冲区,从而浪费资源。
若要使用这些 API 解决此问题,需要在视图转到后台时手动取消收集。 但这听起来是一个样板代码。
这就是为什么谷歌推荐repeatOnLifecycle(Lifecycle.State.XXX)
,使其简单和安全。
repeatOnLifecycle
是一个暂停函数,它将Lifecycle.State
作为参数,用于在生命周期达到该state
时自动创建和启动新的协程,并将块传递给它,并在生命周期低于状态时取消正在执行块的正在进行的协程。
从这里了解更多信息