在我的项目中,我正在使用Firebase Storage下载一些图像文件-精确到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个,但这对我不利。
请帮助。
答案 0 :(得分:2)
您正在启动太多并行下载任务。结果,线程系统放弃了。有关此内容的更多信息: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());
}