Android launchWhenXXX 和 repeatOnLifecycle

编程入门 行业动态 更新时间:2024-10-23 07:19:59

<a href=https://www.elefans.com/category/jswz/34/1771384.html style=Android launchWhenXXX 和 repeatOnLifecycle"/>

Android launchWhenXXX 和 repeatOnLifecycle

文章目录

  • Android launchWhenXXX 和 repeatOnLifecycle
    • lifecycleScope和viewModelScope
    • launchWhenXXX
    • repeatOnLifecycle
    • flowWithLifecycle
    • 总结

Android launchWhenXXX 和 repeatOnLifecycle

lifecycleScope和viewModelScope

LiveData优点:

  • 避免内存泄露风险:当 Activity/Fragment 进入 DESTROYED 时,会自动删除 Observer 。
  • 节省资源:当 Activity/Fragment 进入活跃状态时才开始接受数据,避免 UI 处于后台时的无效计算。

Flow缺点:

Flow 基于协程实现,具有丰富的操作符,通过这些操作符可以实现线程切换、处理流式数据,相比 LiveData 功能更加强大。 但唯有一点不足,无法像 LiveData 那样感知生命周期。

lifecycleScope:

lifecycle-runtime-ktx 库提供了 lifecycleOwner.lifecycleScope 扩展,可以在当前 Activity 或 Fragment 销毁时结束此协程,防止泄露。

Flow 也是运行在协程中的,lifecycleScope 可以帮助 Flow 解决内存泄露的问题。

添加依赖库:

implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.0"
class MyFragment: Fragment() {override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)viewLifecycleOwner.lifecycleScope.launch {val params = TextViewCompat.getTextMetricsParams(textView)val precomputedText = withContext(Dispatchers.Default) {PrecomputedTextCompat.create(longTextContent, params)}TextViewCompat.setPrecomputedText(textView, precomputedText)}}
}
class MyViewModel: ViewModel() {init {viewModelScope.launch {// Coroutine that will be canceled when the ViewModel is cleared.}}
}

launchWhenXXX

由于 lifecycleScope.launch 会立即启动协程,一直运行到协程销毁,不能监听生命周期。因此lifecycle-runtime-ktx 又为我们提供了 LaunchWhenStarted 和 LaunchWhenResumed 。

优点:

launchWhenXXX 会在 XXX 状态前一直等待,又在离开 XXX 状态后挂起协程,lifecycleScope+launchWhenXX的组合使用让 Flow 拥有了生命周期感知能力。

  • 避免泄露:当 lifecycleOwner 进入 DESTROYED 时, lifecycleScope 结束协程
  • 节省资源:当 lifecycleOwner 进入 STARTED/RESUMED 时 launchWhenX 恢复执行,否则挂起。

缺点:

对于 launchWhenXXX 来说, 当 lifecycleOwner 离开 XXX 状态时,协程只是挂起协程而非销毁,如果用这个协程来订阅 Flow,就意味着虽然 Flow 的收集暂停了,但是上游的处理仍在继续,资源浪费的问题解决地不够彻底。

class MyFragment: Fragment {init {lifecycleScope.launchWhenStarted {try {// Call some suspend functions.} finally {// This line might execute after Lifecycle is DESTROYED.if (lifecycle.state >= STARTED) {// Here, since we've checked, it is safe to run any// Fragment transactions.}}}}
}

repeatOnLifecycle

lifecycle-runtime-ktx 自 2.4.0-alpha01 起,提供了一个新的协程构造器 lifecyle.repeatOnLifecycle, 它在离开 X 状态时销毁协程,再进入 X 状态时再启动协程。从其命名上也可以直观地认识这一点,即围绕某生命周期的进出反复启动新协程

class MyFragment : Fragment() {val viewModel: MyViewModel by viewModel()override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)// Create a new coroutine in the lifecycleScopeviewLifecycleOwner.lifecycleScope.launch {// repeatOnLifecycle launches the block in a new coroutine every time the// lifecycle is in the STARTED state (or above) and cancels it when it's STOPPED.viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {// Trigger the flow and start listening for values.// This happens when lifecycle is STARTED and stops// collecting when the lifecycle is STOPPEDviewModel.someDataFlow.collect {// Process item}}}}
}

flowWithLifecycle

当我们只有一个 Flow 需要收集时,可以使用 flowWithLifecycle 这样一个 Flow 操作符的形式来简化代码。

viewLifecycleOwner.lifecycleScope.launch {exampleProvider.exampleFlow().flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.STARTED).collect {// Process the value.}
}

flowWithLifecycle源码:

本质仍然是对 repeatOnLifecycle 的封装。

public fun <T> Flow<T>.flowWithLifecycle(lifecycle: Lifecycle,minActiveState: Lifecycle.State = Lifecycle.State.STARTED
): Flow<T> = callbackFlow {lifecycle.repeatOnLifecycle(minActiveState) {this@flowWithLifecycle.collect {send(it)}}close()
}

总结

  • lifecycleScope.launch:可以在当前 Activity 或 Fragment 销毁时结束此协程,防止泄露。
  • launchWhenXXX:可以像 LiveData 那样感知生命周期,但是会挂起协程而非销毁,仍然存储资源浪费问题。
  • repeatOnLifecycle:可以感知生命周期变化,进入指定状态后会销毁协程。

更多推荐

Android launchWhenXXX 和 repeatOnLifecycle

本文发布于:2023-11-15 00:59:02,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1590862.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Android   launchWhenXXX   repeatOnLifecycle

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!