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

为什么ProgressDialog无法从1到100逐次递增显示进度?

问题原因

你当前的实现是直接将实时下载的真实进度赋值给ProgressDialog,当单次下载的字节块较大时,真实进度的增量会远大于1,就会出现进度跳变的情况,无法实现逐次递增的效果。

解决方案

新增平滑过渡的动画逻辑,让显示的进度匀速追平真实下载进度,既能保证进度逐次从1增加到100,也能和真实下载进度匹配,不会出现进度到100但实际还没下载完的问题。

第一步:新增全局变量

// 存储真实的下载进度
private int realProgress = 0;
// 存储ProgressDialog当前显示的进度
private int currentDisplayProgress = 0;
// 用来调度进度动画的主线程Handler
private Handler progressAnimHandler = new Handler(Looper.getMainLooper());

第二步:新增进度逐次递增的动画任务

private Runnable progressAnimRunnable = new Runnable() {
    @Override
    public void run() {
        // 显示进度没追上真实进度时,逐次加1
        if (currentDisplayProgress < realProgress) {
            currentDisplayProgress++;
            mProgressDialog1.setProgress(currentDisplayProgress);
            // 调整这个延迟值可以修改进度滚动速度,20ms左右肉眼看起来是连续的效果
            progressAnimHandler.postDelayed(this, 20);
        } else if (realProgress >= 100) {
            // 下载完成时关闭弹窗
            mProgressDialog1.dismiss();
        }
    }
};

第三步:修改原有下载进度更新逻辑

不用直接给ProgressDialog设进度,只更新真实进度值即可:

final float downloadProgress = downloadedBytes * 100f / totalBytes;
// 赋值真实进度,避免超过100
realProgress = (int) Math.min(downloadProgress, 100);
if (downloadProgress > 99.9) {
    realProgress = 100;
    progressTimer.cancel();
}
// 动画任务只需要启动一次,避免重复执行
if (!progressAnimHandler.hasCallbacks(progressAnimRunnable)) {
    progressAnimHandler.post(progressAnimRunnable);
}

第四步:补充资源回收逻辑

在页面销毁、下载取消的位置加下面的代码,避免内存泄漏:

progressAnimHandler.removeCallbacks(progressAnimRunnable);

补充说明

如果你不需要进度和真实下载速度匹配,只要固定匀速从1涨到100,直接把动画逻辑改成每次固定加1,直到到100即可,不过该方式不推荐,会误导用户对下载完成时间的判断。

内容的提问来源于stack exchange,提问作者Jimmy Guetta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 03:48:04