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

Kotlin下载进度监听重复打印问题求助及Jetpack Compose适配需求

排查下载进度重复打印的原因及修复方案

常见重复打印原因及排查步骤

  • 重复注册进度回调:检查AndroidDownloader中是否每次启动下载都注册新监听器且未清理旧监听器,导致同一个进度事件触发多次回调。
  • Flow订阅未处理重复事件:若用Flow传递进度,使用collect而非collectLatest时,旧的收集逻辑可能未完成就触发新打印。
  • 下载任务被多次启动:检查startDownload的调用逻辑,是否因按钮重复点击、生命周期回调重复触发等导致多任务并行,每个任务都输出进度日志。
  • Compose重组触发重复打印:若在Composable函数中直接打印进度,每次重组都会执行打印逻辑,需将打印移至ViewModel或用LaunchedEffect包裹。

针对性修复示例

1. 修复监听器重复注册问题

修改AndroidDownloader的监听器管理逻辑,确保同一时间仅保留一个有效监听器:

class AndroidDownloader {
    private var downloadListener: DownloadProgressListener? = null

    // 设置监听器时直接覆盖旧实例
    fun setProgressListener(listener: DownloadProgressListener) {
        downloadListener = listener
    }

    private fun updateProgress(progress: Int) {
        downloadListener?.onProgressUpdated(progress)
    }
}

2. Flow订阅使用collectLatest

改用collectLatest确保只处理最新的进度事件,避免旧回调重复执行:

// 在ViewModel或Composable的LaunchedEffect中
LaunchedEffect(Unit) {
    downloader.downloadProgressFlow.collectLatest { progress ->
        Log.d("Download", "当前进度: $progress%")
    }
}

3. 防止下载任务重复启动

给startDownload添加防重复逻辑:

class AndroidDownloader {
    private var isDownloading = false

    fun startDownload(url: String) {
        if (isDownloading) return
        isDownloading = true
        // 执行下载逻辑
    }

    private fun onDownloadComplete() {
        isDownloading = false
        // 完成后续处理
    }
}

Jetpack Compose UI实现建议

结合MutableState与LinearProgressIndicator实现实时进度展示:

// ViewModel中维护进度状态
class DownloadViewModel : ViewModel() {
    val downloadProgress = mutableStateOf(0f)

    fun startDownload() {
        viewModelScope.launch {
            downloader.downloadProgressFlow.collectLatest { progress ->
                downloadProgress.value = progress / 100f
            }
        }
    }
}

// Composable组件
@Composable
fun DownloadScreen(viewModel: DownloadViewModel = viewModel()) {
    val progress by viewModel.downloadProgress

    Column(
        modifier = Modifier.fillMaxSize().padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        LinearProgressIndicator(
            progress = progress,
            modifier = Modifier.fillMaxWidth().height(8.dp)
        )
        Text(
            text = "${(progress * 100).toInt()}%",
            modifier = Modifier.padding(top = 16.dp),
            fontSize = 18.sp
        )
        Button(
            onClick = { viewModel.startDownload() },
            modifier = Modifier.padding(top = 32.dp)
        ) {
            Text("开始下载")
        }
    }
}

内容的提问来源于stack exchange,提问作者Joe Mama Jr.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 23:27:27