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

for循环内addOnSuccessListener无法关闭ProgressDialog 多图上传如何关闭进度框

解决方案

核心逻辑:Firebase的文件上传、下载链接获取都是异步执行的,你不能直接在for循环结束的位置关闭弹窗——此时所有上传任务还在后台执行,没有完成。你需要统计所有任务的完成状态,等到全部文件上传成功、且所有下载链接都获取存储完成后再关闭进度弹窗。

具体修改如下:

  1. 新增线程安全的计数器,统计已完成的有效任务数(必须是拿到下载链接并存储完成才算1个完成任务)
  2. 每次成功存储下载链接后对计数器+1,当计数器数值等于总上传任务数时,关闭弹窗、执行后续的Firebase Database写入操作
  3. 原有失败逻辑保留,只要有一个任务失败就直接关闭弹窗提示错误

修改后的完整代码:

// 先给你的类新增一个成员变量,存储进度弹窗引用,方便后续访问
private ProgressDialog mDialog;

private void uploadScreenshot() {
    // 多图上传建议修改判断条件,原来的screenshotUri大概率是单图上传的遗留判断
    if (ScreenshotList != null && !ScreenshotList.isEmpty()) {
        mDialog = new ProgressDialog(this);
        mDialog.setMessage("Uploading...");
        mDialog.setCancelable(false); // 建议加上,避免用户手动取消导致任务状态混乱
        mDialog.show();

        // 总上传任务数
        final int totalUploadTasks = ScreenshotList.size();
        // 线程安全的计数器,避免多线程场景下计数错误
        final AtomicInteger completedTaskCount = new AtomicInteger(0);

        String ssName = UUID.randomUUID().toString();
        final StorageReference screenshotFolder = storageReference.child("screenshots/" + ssName);

        for (int upload_count = 0; upload_count < ScreenshotList.size(); upload_count++) {
            Uri IndividualImage = Uri.parse(ScreenshotList.get(upload_count));
            final StorageReference ScreenshotName = screenshotFolder.child(IndividualImage.getLastPathSegment());

            ScreenshotName.putFile(IndividualImage)
            .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                    ScreenshotName.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                        @Override
                        public void onSuccess(Uri uri) {
                            String url = String.valueOf(uri);
                            storeLink(url, completedTaskCount, totalUploadTasks);
                        }
                    });
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    if (mDialog != null && mDialog.isShowing()) {
                        mDialog.dismiss();
                    }
                    Toast.makeText(AppList.this, "" + e.getMessage(), Toast.LENGTH_SHORT).show();
                }
            })
            .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                    double progress = (100.0 * taskSnapshot.getBytesTransferred() / taskSnapshot.getTotalByteCount());
                    mDialog.setMessage("Uploaded " + (int)progress + "%");
                }
            });
        }
    }
}


private void storeLink(String url, AtomicInteger completedTaskCount, int totalTasks) {
    ssList.add(url);
    newApp.setScreenshot(ssList);

    // 计数器自增,判断是否所有任务都完成
    int currentCompleted = completedTaskCount.incrementAndGet();
    if (currentCompleted == totalTasks) {
        // 所有任务完成,关闭弹窗
        if (mDialog != null && mDialog.isShowing()) {
            mDialog.dismiss();
        }
        // 这里执行你要的newApp写入Firebase Database的操作
        Toast.makeText(AppList.this, "Screenshots Uploaded !!!", Toast.LENGTH_SHORT).show();
    }
}

补充说明:如果你的minSDK版本较高,也可以用Tasks.whenAllSuccess()批量监听所有任务的完成状态,逻辑会更简洁,上面的方案是兼容所有版本的通用写法。

内容的提问来源于stack exchange,提问作者Amit Swami

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 19:36:03