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

Android Studio中前置Firebase循环为何晚于后续语句执行

问题根因

你遇到的执行顺序异常是Firebase Storage API的所有操作都是异步执行导致的:

  • putFile、getDownloadUrl方法都不会阻塞主线程,调用后立刻返回,主线程会继续往下执行后续代码
  • 你传入的OnSuccessListener回调只有等后台线程完成对应的上传/获取地址操作后,才会切回主线程执行
  • 所以循环只是把所有上传任务提交出去就立刻结束了,主线程马上执行了后面的Log.d("list","method called")和addtodatabase调用,等后续上传任务逐个完成后,才会执行回调里的打印和链接收集逻辑,自然就出现了顺序颠倒的情况。

修复方案

可以通过上传成功计数判断所有任务是否完成,再执行后续的数据库写入逻辑,修改后的代码逻辑如下:

private void uploadfirebase() {
    hashMap.put("Images", "nnn");
    hashMap.put("Title", "tit");
    String childer = System.currentTimeMillis() + FirebaseAuth.getInstance().getCurrentUser().getUid();
    databaseReference.child(FirebaseAuth.getInstance().getCurrentUser().getUid()).setValue(hashMap).addOnSuccessListener(new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {
            Toast.makeText(UploadImages.this, "Done", Toast.LENGTH_SHORT).show();
        }
    });
    ProgressDialog progressDialog = new ProgressDialog(this);
    progressDialog.setMessage("Uploading");
    progressDialog.show();
    // 记录总上传数、成功计数
    int totalUpload = imagePath.size();
    AtomicInteger successCount = new AtomicInteger(0);
    // 空列表特殊处理
    if (totalUpload == 0) {
        progressDialog.dismiss();
        addtodatabase(addToFirebaseUris);
        return;
    }
    for (int i = 0; i < imagePath.size(); i++) {
        Uri uri = Uri.fromFile(new File(imagePath.get(i)));
        String currenttime = System.currentTimeMillis() + FirebaseAuth.getInstance().getCurrentUser().getUid();
        storageReference.child(currenttime).putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                taskSnapshot.getStorage().getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                    @Override
                    public void onSuccess(Uri uri) {
                        String url = String.valueOf(uri);
                        addToFirebaseUris.add(url);
                        Log.d("list", "addtoFirebaseList size : " + addToFirebaseUris.size());
                        // 计数+1,判断是否全部上传完成
                        int current = successCount.incrementAndGet();
                        if (current == totalUpload) {
                            progressDialog.dismiss();
                            Log.d("list", "method called");
                            Toast.makeText(UploadImages.this, "所有图片上传完成", Toast.LENGTH_SHORT).show();
                            try {
                                addtodatabase(addToFirebaseUris);
                            } catch (Exception e) {
                                Toast.makeText(UploadImages.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                            }
                        }
                    }
                });
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                progressDialog.dismiss();
                Toast.makeText(UploadImages.this, e.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

修改说明

  • 新增totalUpload记录需要上传的图片总数,新增AtomicInteger类型的successCount记录已成功获取下载链接的数量,保证多回调并发场景下计数正确
  • 把原本写在循环外的addtodatabase调用、完成日志等逻辑,移到每次下载链接获取成功的回调里,判断所有任务都完成后再执行
  • 增加空列表判断,避免没有图片需要上传时进度条一直显示的问题

内容的提问来源于stack exchange,提问作者Naman Mandliya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:48:03