当我在 Android 中将文件上传到 Firebase 存储时,进度条没有更新

Posted

技术标签:

【中文标题】当我在 Android 中将文件上传到 Firebase 存储时,进度条没有更新【英文标题】:Progress Bar Not Updating When I Upload Files To Firebase Storage in Android 【发布时间】:2021-12-22 05:02:08 【问题描述】:

让我解释一下整个场景,我想将文件上传到 Firebase,所以我制作了一个布局,其中我有一个用于选择文件的按钮、一个滚动视图和一个回收器视图,无论我从我的设备中选择什么文件它显示在回收站视图并开始上传。这是我的按钮的代码以及它是如何上传的。这是在文件 UploadActivity.java

当用户选择多个文件时,如果条件为真,当用户选择单个文件时,将执行 Else 部分。 (这是有问题的区域)

ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        result -> 
            Intent intentReceived = result.getData();
            ClipData clipData = result.getData().getClipData();
            if (clipData != null) 
                for (int i = 0; i < intentReceived.getClipData().getItemCount(); i++) 
                    Uri fileUri = intentReceived.getClipData().getItemAt(i).getUri();
                    String fileName = UploadActivity.this.getFileNameFromUri(fileUri);
                    uploadFiles.add(fileName);
                    uploadStatus.add("Loading");
                    adapter.notifyDataSetChanged();

                    final int index = i;

                    //Uploading File To Firebase Storage
                    StorageReference uploader = storageReference.child("/" + Path).child(fileName);
                    uploader.putFile(fileUri)
                            .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() 
                                @Override
                                public void onProgress(@NonNull UploadTask.TaskSnapshot snapshot) 
                                    try
                                        progressValue.remove(index);
                                    catch(Exception e)
                                        //Do Nothing
                                    
                                    double progress = (100.0 * snapshot.getBytesTransferred()) / snapshot.getTotalByteCount();
                                    int currentProgress = (int) progress;
                                    Integer passProgress = Integer.valueOf(currentProgress);
                                    try
                                        progressValue.add(index,passProgress);
                                    catch (Exception e)
                                        progressValue.add(passProgress);
                                    
                                    uploadStatus.remove(index);
                                    uploadStatus.add(index, "Processing");
                                    adapter.notifyDataSetChanged();
                                
                            );

这是更新此 UploadActivity 中进度条值的数组列表。

ArrayList<Integer> progressValue;

所有这些值都将在 RecyclerView 适配器中更改,以反映上传活动中存在的 RecyclerView 的更改。 (仅供参考)

@Override
public void onBindViewHolder(@NonNull uploadViewHolder holder, int position) 
    String fileName = files.get(position);
    if(fileName.length() > 25)
        fileName = fileName.substring(0,25)+"...";
    holder.uploadFileName.setText(fileName);

    String fileStatus = status.get(position);
    if(fileStatus.equals("Processing"))
        int updateProgress = progress.get(position).intValue();
        holder.uploadProgressBar.setProgress(updateProgress);
    
    if(fileStatus.equals("Done"))
        holder.uploadProgressBar.setProgress(0);
        holder.uploadProgressBar.setVisibility(View.GONE);
        holder.uploadComplete.setImageResource(R.drawable.check_circle);
    


@Override
public int getItemCount() 
    return files.size();

注意:当我第一次选择文件时,它不会产生任何问题,它会在上传完成时显示适当增加的进度条和检查图标。但是如果我再次选择文件,那么文件会成功上传,但进度条不起作用并且甚至复选标记(我在上传完成时设置复选标记图标)也没有显示。但是,如果当我返回并单击上传按钮时 UploadActivity 再次启动,那么它再次完美运行。

【问题讨论】:

有很多代码需要我们解析,但不清楚代码的哪一部分失败了,或者您做了什么故障排除。请花点时间查看How to create a Minimal, Complete, and Verifiable example。减少代码,澄清问题,我们来看看。 @Jay 我已更改代码并标记了仅在 OnProgressListener 中的问题区域 【参考方案1】:

这可能会帮助您,也可能不会,但会重构您的适配器以适应 1 个且只有 1 个数据列表。您目前似乎正在调整 3 个列表,这使您的逻辑更加复杂。您有文件、进度和状态列表。

这是一个示例模型,应该代表您正在适应的内容。

public class FileModel 
   private String name;
   private int progress = 0;
   private String status = "Loading";

   public FileModel(String name)
      this.name = name;
   
   public String getName()return name;
   public int getProgress() return progress;
   public String getStatus() return status;
   public void setProgress(int progress) this.progress = progress;
   public void setStatus(String status) this.status = status;

在您的适配器内部,您希望使用 diff 回调来区分新旧项目。 这是简单的差异回调 https://medium.com/android-news/smart-way-to-update-recyclerview-using-diffutil-345941a160e0

在你的进步中聆听者

@Override
public void onProgress(@NonNull UploadTask.TaskSnapshot snapshot) 
    double progress = (100.0 * snapshot.getBytesTransferred()) / snapshot.getTotalByteCount();
    //The model pertaining to this file.
    fileModel.setProgress((int) progress);
    //create a new function in your adapter to re-set the list
    //with the new changes.
    //don't worry its very fast with diff callback
    adapter.setList(fileModels);

【讨论】:

哇,这对我来说是全新的概念来更新 RecyclerView.. 让我试试这个.. :D 嘿,我需要更多帮助。你能详细说明一下 fileModel 和 setList(fileModels)。如果是,fileModels 是一个 ArrayList 所以当我在这个列表中添加项目时因为我直接将数据更改为 fileModel 类。

以上是关于当我在 Android 中将文件上传到 Firebase 存储时,进度条没有更新的主要内容,如果未能解决你的问题,请参考以下文章

如何在Android中将视频上传到youtube?

如何在 Android 中将文件上传到 Cloudinary 时显示进度?

在 1 个请求中将多个文件从 Android 上传到 AppEngine

如何在 Android 中将视频上传到 YouTube?

在未找到android studio照片中将图像上传到网站

在 Flutter 中将 Firebase 数据作为 Listview 构建器获取