You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Fragment每次调用onResume时重新启动协程?

解决Fragment每次onResume重启协程的问题

你的代码问题在于launchWhenResumed只会在Fragment首次进入Resumed状态时执行一次协程逻辑,后续再次触发onResume时,这个协程已经完成或处于运行状态,不会重新执行内部的Flow收集逻辑,导致后续onResume没有反应。下面是两种正确的实现方式:

方法一:使用repeatOnLifecycle(官方推荐)

这是Jetpack Lifecycle库提供的最佳实践,它会自动在每次进入指定生命周期状态时执行逻辑,离开时取消协程,下次进入时重新启动。

val renderer = ...
val outerFlow = ...
val lifecycleScope = myFragment.viewLifecycleOwner.lifecycleScope

lifecycleScope.launch {
    // 每次进入RESUMED状态时执行块内逻辑,离开时取消
    repeatOnLifecycle(Lifecycle.State.RESUMED) {
        outerFlow.collect(renderer::render)
        // 如果你需要在collect前做额外处理,也可以用onEach:
        // outerFlow.onEach(renderer::render).collect()
    }
}

原理:repeatOnLifecycle会监听生命周期变化,当Fragment进入RESUMED状态时,启动Flow的收集协程;当Fragment离开RESUMED(比如进入PAUSED)时,自动取消这个收集协程。下次回到RESUMED时,会重新启动收集,完美匹配每次onResume重启协程的需求。

方法二:手动监听生命周期回调

如果需要更手动的控制,可以在Fragment的onResume中启动协程,onPause中取消之前的协程:

private var renderJob: Job? = null
val renderer = ...
val outerFlow = ...

override fun onResume() {
    super.onResume()
    // 每次onResume启动新的协程
    renderJob = viewLifecycleOwner.lifecycleScope.launch {
        outerFlow.collect(renderer::render)
    }
}

override fun onPause() {
    // 离开时取消协程,避免泄漏
    renderJob?.cancel()
    renderJob = null
    super.onPause()
}

注意:这种方法需要手动管理Job的生命周期,不如repeatOnLifecycle优雅,容易出现遗漏取消的情况,因此优先推荐第一种方法。

内容的提问来源于stack exchange,提问作者Denis Perfomer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 14:20:28