【问题标题】:Firebase Storage RejectedExecutionException exceptionFirebase 存储 RejectedExecutionException 异常
【发布时间】:2019-03-18 20:28:53
【问题描述】:

在我的项目中,我使用 Firebase 存储来下载一些图像文件 - 确切地说是 154 个图像。出于某种未知的原因,我只下载了大约 130 个文件,然后我得到一个异常说明:

java.util.concurrent.RejectedExecutionException: Task com.google.firebase.storage.zzs@15c1d59d rejected from java.util.concurrent.ThreadPoolExecutor@270bfa12[Running, pool size = 3, active threads = 3, queued tasks = 128, completed tasks = 5]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2011)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:793)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1339)
    at com.google.firebase.storage.zzu.zzv(Unknown Source)
    at com.google.firebase.storage.FileDownloadTask.schedule(Unknown Source)
    at com.google.firebase.storage.StorageTask.zzcny(Unknown Source)
    at com.google.firebase.storage.StorageReference.getFile(Unknown Source)
    at com.google.firebase.storage.StorageReference.getFile(Unknown Source)

我正在使用 for 循环调用 StorageReference.getFile() 并将文件下载到特定位置,如下所示:

        for (int i = 0; i < filesToDownload.size(); i++) {
            String image = filesToDownload.get(i);

            final File localFile = new 
               File(DeviceStorage.getExternalStorageDir(dirPath)
               + File.separator + fileName);
            StorageReference downloadPhotoRef = 
               getReference().child(folderName + File.separator + fileName);

            downloadPhotoRef.getFile(localFile);
            downloadFile(context, image);
        }

我真的很困惑为什么会发生这种情况。我找不到任何解决方案,其他人也有同样的问题。 我在服务中运行此代码。我没有得到错误的唯一方法是如果我下载的文件少于 130 个,但这对我没有好处。

请帮忙。

【问题讨论】:

    标签: java android firebase firebase-storage


    【解决方案1】:

    您正在启动太多并行下载任务。结果,线程系统放弃了。更多相关信息:https://stackoverflow.com/a/8183463/679553

    你应该尝试序列化这个过程的一部分,也许10乘10下载? .continueWith() 这是一个好的开始:https://firebase.googleblog.com/2016/09/become-a-firebase-taskmaster-part-3_29.html

    此时您的getFile() 调用会产生一个新的下载任务并返回而不会阻塞。您可以在上一次下载完成后使用 .continueWith() 启动它,而不是使用 for 循环的下一次迭代开始下一次下载。

    实现这一点的一种方法是创建一个函数,该函数返回一个任务并在最后一个continueWith 块中调用自身。有点像这里的 C# 示例表单:https://stackoverflow.com/a/49043177/679553

    我修改了该链接中的一个示例,使其更接近您的情况。我在移动设备上,所以这是我目前能做的最好的事情:) 您可以将 ref 设为您班级中的一个字段,并在 continueWith 块内更新它。

    Task DoStuff()
    {
        return ref.getFile(() => DoWork1())
            .ContinueWith((t1) => DoWork2())
            .ContinueWith(t2 => DoWork3())
            .ContinueWith(t3=> DoStuff());
    }
    

    【讨论】:

    • 好的,这是一个很好的开始。我唯一要得到的是如何在我的情况下实现 .continueWith() 。 firebase 博客文章中的所有示例都具有已知数量的任务,这与我的情况不同,我的数组大小是动态值。我尝试了另一件事:在 getFile() 的“addOnSuccessListener”中初始化“i”变量,但由于某种原因,执行从未进入 addOnSuccessListener
    • 我从“一种方式...”开始编辑了我的答案。我现在正在使用移动设备,但我过去曾这样做过,这样的事情会奏效。
    • 谢谢,我认为这解决了我的问题!你确实很有帮助!
    猜你喜欢
    • 1970-01-01
    • 2019-01-05
    • 1970-01-01
    • 1970-01-01
    • 2018-04-26
    • 2017-03-26
    • 2020-02-29
    • 1970-01-01
    • 2020-08-02
    相关资源
    最近更新 更多