Reputation: 1
I am trying to create a backup photos app.
The app should upload all images into Firebase. When I start it the app uploads several photos perfectly but then crashes with this report.
java.util.concurrent.RejectedExecutionException: Task com.google.firebase.storage.StorageTask$8@e245bda rejected from java.util.concurrent.ThreadPoolExecutor@e13b80b[Running, pool size = 2, active threads = 2, queued tasks = 128, completed tasks = 0]
The code:
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);
}
}
}
}
Upvotes: 0
Views: 281
Reputation: 46
The easiest and most efficient way to overcome this situation is by using Thread.sleep(SLEEP_TIME);
after the putFile call along with a counter variable.
Example:
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 : The number of files after which you have to pause the thread to wait for the upload to complete.
TIME_REQUIRED_FOR_BATCH_UPLOAD : You have to find out your upload time in milliseconds for the said amount of files. (considering all are of similar size. other improvise.)
Upvotes: 0
Reputation: 2727
I think the problem is with this line in loop
StorageReference riversRef = storage_photos.child(uri.getLastPathSegment());
Because for every item in loop you are making a whole new reference , resulting a queue of 128 tasks. And when you put file it asynchronously uploads the file so you are making alot of async tasks.
Upvotes: 1
Reputation: 69689
queued tasks = 128 indicates that you have reached maximum count of tasks implementation before kitkat can queue only 128 tasks. Above which it will issue RejectedExecutionException. So I would suggest you reduce the number of task created.
Upvotes: 0