Android 将多个图像上载到firebase存储

Android 将多个图像上载到firebase存储,android,firebase,firebase-storage,Android,Firebase,Firebase Storage,我正在尝试将几个图像上载到firebase存储。 我为此编写了以下代码:- private static void uploadImage(String imageUrl) { FirebaseStorage storage = FirebaseStorage.getInstance(); final StorageReference storageRef = storage.getReferenceFromUrl("gs://image-stor

我正在尝试将几个图像上载到firebase存储。 我为此编写了以下代码:-

    private static void uploadImage(String imageUrl)
    {
        FirebaseStorage storage = FirebaseStorage.getInstance();
        final StorageReference storageRef = storage.getReferenceFromUrl("gs://image-store.appspot.com/");
        Uri file = Uri.fromFile(new File(imageUrl));
        String imageName = System.currentTimeMillis()+".jpg"; 
        StorageReference imageRef = storageRef.child("images").child(imageName);
        UploadTask uploadTask = imageRef.putFile(file);
    }

    private static uploadImages(String[] imageUrls)
    {
        for(imageUrl : imageUrls)
        {
            uploadImage(imageUrl)
        }
    }
当需要上传的图像较少时,上述代码可以正常工作。但是当有大约100多个映像时,它会创建多个异步线程,并给出以下错误:-

Exception java.util.concurrent.RejectedExecutionException: Task com.google.firebase.storage.StorageTask$5@ef10d00 rejected from java.util.concurrent.ThreadPoolExecutor@1c98b939[Running, pool size = 2, active threads = 2, queued tasks = 128, completed tasks = 59]
java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution (ThreadPoolExecutor.java:2042)
java.util.concurrent.ThreadPoolExecutor.reject (ThreadPoolExecutor.java:796)
java.util.concurrent.ThreadPoolExecutor.execute (ThreadPoolExecutor.java:1370)
com.google.firebase.storage.zzd.zzu ()
com.google.firebase.storage.UploadTask.schedule ()
com.google.firebase.storage.StorageTask.an ()
com.google.firebase.storage.StorageReference.putFile ()
com.indiacom.blanketfos.util.FirebaseUtil.uploadImage (FirebaseUtil.java:64)
com.indiacom.blanketfos.util.FirebaseUtil.uploadImages (FirebaseUtil.java:126)
com.indiacom.blanketfos.util.FirebaseUtil.syncRealmToFirebase (FirebaseUtil.java:33)
com.indiacom.blanketfos.ui.FormActivity.onOptionsItemSelected (FormActivity.java:406)
android.app.Activity.onMenuItemSelected (Activity.java:2983)
android.support.v4.app.FragmentActivity.onMenuItemSelected (FragmentActivity.java:408)
android.support.v7.app.AppCompatActivity.onMenuItemSelected (AppCompatActivity.java:195)
android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected (WindowCallbackWrapper.java:113)
android.support.v7.app.AppCompatDelegateImplV9.onMenuItemSelected (AppCompatDelegateImplV9.java:675)
android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected (MenuBuilder.java:822)
android.support.v7.view.menu.MenuItemImpl.invoke (MenuItemImpl.java:156)
android.support.v7.view.menu.MenuBuilder.performItemAction (MenuBuilder.java:969)
android.support.v7.view.menu.MenuBuilder.performItemAction (MenuBuilder.java:959)
android.support.v7.widget.ActionMenuView.invokeItem (ActionMenuView.java:623)
android.support.v7.view.menu.ActionMenuItemView.onClick (ActionMenuItemView.java:154)
android.view.View.performClick (View.java:4781)
android.view.View$PerformClick.run (View.java:19907)
android.os.Handler.handleCallback (Handler.java:739)
android.os.Handler.dispatchMessage (Handler.java:95)
android.os.Looper.loop (Looper.java:160)
android.app.ActivityThread.main (ActivityThread.java:5541)
java.lang.reflect.Method.invoke (Method.java)
java.lang.reflect.Method.invoke (Method.java:372)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:964)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:759)

因此,我的问题是,将多个图像上载到firebase存储而不出现此类问题的最佳和最有效的方法是什么。

我也遇到了同样的问题,并发现firebase存储只接受免费最多100次并发上载。以下是我所做的,希望能有所帮助:

private static void uploadFS(final File[] files, final StorageReference certRef, int startIndex, int concurrent) {
    int cnt = 0;
    File file;
    Uri uriFile;
    StorageReference ref;
    while (cnt < concurrent) {
        file = files[startIndex];
        startIndex++;
        if (file.exists() && file.length() > 0) { // local cert file exits
            uriFile = Uri.fromFile(file);
            final int sIdx = startIndex;
            ref = certRef.child("cert/" + uriFile.getLastPathSegment());
            ref.putFile(uriFile).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                    uploadFS(files, certRef, sIdx, 1);
                }
            });
        }
        cnt++;
    }
}
public static void uploadCert() {
    StorageReference rootStorageRef = getStorageRefRoot();
    if (rootStorageRef != null) { // loop through download folder
        File certFolder = new File(MainActivity.DOWNLOAD_FULL_PATH + "cert/");
        if (certFolder.isDirectory()) {
            File[] certFiles = certFolder.listFiles();
            uploadFS(certFiles, rootStorageRef, 0, 3);  // 3 is concurrent upload tasks
        }
    }
}
private static void uploadFS(最终文件[]文件,最终存储引用certRef,int startIndex,int并发){
int-cnt=0;
文件;
Uri文件;
存储参考文献;
while(cnt0){//本地证书文件退出
uriFile=Uri.fromFile(文件);
最终int sIdx=起始索引;
ref=certRef.child(“cert/”+uriFile.getLastPathSegment());
ref.putFile(uriFile).addOnSuccessListener(新的OnSuccessListener(){
@凌驾
成功时公共无效(UploadTask.TaskSnapshot TaskSnapshot){
上传文件(文件,certRef,sIdx,1);
}
});
}
cnt++;
}
}
公共静态无效上载证书(){
StorageReference rootStorageRef=getStorageRefRoot();
如果(rootStorageRef!=null){//循环下载文件夹
File certFolder=新文件(MainActivity.DOWNLOAD_FULL_PATH+“cert/”);
if(certFolder.isDirectory()){
File[]certFiles=certFolder.listFiles();
uploadFS(certFiles,rootStorageRef,0,3);//3是并发上载任务
}
}
}

并行上传100张图片听起来不是个好主意。我会使用更合理的并行上传次数(比如3-5次),并且只在现有上传完成后才开始新的上传(你可以)。如果你将执行器限制在设备上的内核数,比如4个,那么它就可以工作了。但这当然会让一切变得更慢。发布到Firebase实时数据库是可以的,但我想这是非常快的,而上传是缓慢的,并抓住一个线程。可能只有在所有上传任务完成后,您才应该在executor中启动新的runnabletask?使用AddOnCompleteSistener向处理程序发送一条空消息,以便重新启动下载/上传。这对我有用。