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

如何在Kotlin Fragment的onResume中重启Coroutine并恢复上次位置

问题描述

我希望在应用中使用Coroutines和循环函数,要求Fragment进入onDestroyView生命周期时取消该协程任务,进入onResume时重新启动任务并从之前的位置继续执行。我已实现onDestroyView中的取消逻辑,但不清楚如何在onResume中重启并恢复执行位置,现有代码如下:

private val bannerJob = CoroutineScope(Main)

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    bannerJob.launch {
        repeat(REPEAT_TIME) {
            delay(DELAY_TIME)
            if (autoScrollIndex < list.size) {
                autoScrollIndex += 1
            } else {
                autoScrollIndex = 0
            }
            binding.list.scrollToPosition(autoScrollIndex)
        }
    }
}

override fun onDestroyView() {
    super.onDestroyView()
    bannerJob.cancel()
}

解决方案

要实现协程重启并从上次位置继续执行,需要调整几个核心逻辑,修改后的代码如下:

// 用Fragment自带的lifecycleScope替代自定义CoroutineScope,自动绑定生命周期
private var autoScrollIndex = 0
private var currentBannerJob: Job? = null

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    startBannerAutoScroll()
}

override fun onResume() {
    super.onResume()
    startBannerAutoScroll()
}

override fun onPause() {
    super.onPause()
    currentBannerJob?.cancel()
}

override fun onDestroyView() {
    super.onDestroyView()
    currentBannerJob?.cancel()
}

private fun startBannerAutoScroll() {
    // 先取消已有任务,避免多个协程同时运行
    currentBannerJob?.cancel()
    currentBannerJob = lifecycleScope.launch {
        while (isActive) { // 基于协程存活状态实现无限循环,取消时自动终止
            delay(DELAY_TIME)
            // 简化索引循环逻辑
            autoScrollIndex = (autoScrollIndex + 1) % list.size
            binding.list.scrollToPosition(autoScrollIndex)
        }
    }
}

关键说明

  • 协程作用域选择:使用lifecycleScope(Fragment内置协程作用域),它会在Fragment销毁时自动取消所有协程,避免内存泄漏,比自定义CoroutineScope更安全。
  • 任务管理:用currentBannerJob变量跟踪当前运行的协程,每次启动前先取消旧任务,确保同一时间只有一个轮播协程在执行。
  • 状态保留:autoScrollIndex作为Fragment成员变量,只要Fragment实例未被销毁,就能保留上次的位置,重启协程时直接从该位置继续。
  • 循环逻辑优化:用(autoScrollIndex + 1) % list.size替代原有的条件判断,代码更简洁且能实现无限循环轮播。
  • 生命周期绑定:在onPause和onDestroyView中取消任务,在onViewCreated和onResume中重启,保证Fragment可见时轮播运行,不可见时暂停。

如果需要在Fragment销毁后仍保留autoScrollIndex,可以将其存入SavedStateHandle(配合ViewModel使用),确保配置变更或Fragment重建时不丢失状态。

内容的提问来源于stack exchange,提问作者Dali Hasan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 05:42:58