我正在尝试创建备用照片应用。
该应用应将所有图片上传到Firebase。当我启动它时,应用程序会完美地上传几张照片,但随后会与此报告崩溃。
java.util.concurrent.RejectedExecutionException:任务com.google.firebase.storage.StorageTask$8@e245bda从java.util.concurrent.ThreadPoolExecutor@e13b80b拒绝[正在运行,池大小= 2,活动线程= 2,排队任务= 128,已完成任务= 0]
代码:
StorageReference storage_photos=FirebaseStorage.getInstance().getReference();
private void tryToTakePhotos() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
try {
final String[] columns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID};
final String orderBy = MediaStore.Images.Media._ID;
//Stores all the images from the gallery in Cursor
Cursor cursor = getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null,
null, orderBy);
int count = cursor.getCount();
int dataColumnIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
Toast.makeText(this, "dd" + count, Toast.LENGTH_SHORT).show();
storage_photos = storage_photos.child(name + "---" + count + "photos");
for (int i = 0; i < count; i++) {
cursor.moveToPosition(i);
String filePath = cursor.getString(dataColumnIndex);
//Bitmap bitmap = BitmapFactory.decodeFile(filePath);
File file = new File(filePath);
Uri uri = Uri.fromFile(file);
StorageReference riversRef = storage_photos.child(uri.getLastPathSegment());
riversRef.putFile(uri);
}
cursor.close();
Calendar calendar = Calendar.getInstance();
firebase_takePhotos.setValue("taken at: " + calendar.get(Calendar.DAY_OF_MONTH) + "-"
+ (calendar.get(Calendar.MONTH) + 1) + "-"
+ calendar.get(Calendar.YEAR));
}catch (Exception e){
firebase_takePhotos.setValue(""+e);
}
}
}
}
答案 0 :(得分:1)
我认为问题在于循环中的这一行
StorageReference riversRef = storage_photos.child(uri.getLastPathSegment());
因为对于循环中的每个项目,您正在进行全新的引用,从而产生128个任务的队列。当您放置文件时,它会异步上传文件,因此您可以进行大量的异步任务。
答案 1 :(得分:0)
排队的任务= 128表示您已达到最大任务数 kitkat之前的实现只能排队128个任务。在它之上它将发出RejectedExecutionException。所以我建议你减少创建的任务数量。
答案 2 :(得分:0)
克服这种情况最简单有效的方法是在putFile调用后使用Thread.sleep(SLEEP_TIME);
和计数器变量。
示例:
private int fileCounter = 0;
private final int FILE_BATCH_COUNT = 50; //50 files
private final int TIME_REQUIRED_FOR_BATCH_UPLOAD = 5*60000; //5 min, varies according to your internet speed
//...
private void yourFunction(){
//...
fileCounter = fileCounter + 1;
mStorageRef.putFile(fileUri).addOnSuccessListener(...).addOnFailiureListener(...);
if(fileCounter >= FILE_BATCH_COUNT){
Thread.sleep(TIME_REQUIRED_FOR_BATCH_UPLOAD);
fileCounter = 0;
}
}
FILE_BATCH_COUNT:您必须暂停线程以等待上传完成的文件数。
TIME_REQUIRED_FOR_BATCH_UPLOAD:您必须找到上述文件数量的上传时间(以毫秒为单位)。 (考虑到所有人都有相似的规模。其他即兴创作。)