1

So the thing is that i want to get Bitmap from absolute path, so i pass those paths as ArrayList<Strings> to my presenter, where i have next piece of code:

private void decodeImageUri(final ArrayList<String> imageUris) {

    while(imageCounter < imageUris.size()) {
        DecodeBitmapsThreadPool.post(new Runnable() {
            @Override
            public void run() {

                Bitmap bitmap = BitmapFactory.decodeFile(imageUris.get(imageCounter));

                mImagesBase64Array.add(bitmapToBase64(bitmap));
            }
        });
    }
    DecodeBitmapsThreadPool.finish();
    Log.d("SIZE OF BASE64", " ---------- " + mImagesBase64Array.size());

}

And this is my ThreadPool class:

public class DecodeBitmapsThreadPool {

private static DecodeBitmapsThreadPool mInstance;
private ThreadPoolExecutor mThreadPoolExec;
private static int MAX_POOL_SIZE;
private static final int KEEP_ALIVE = 10;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();

public static synchronized void post(Runnable runnable) {
    if (mInstance == null) {
        mInstance = new DecodeBitmapsThreadPool();
    }
    mInstance.mThreadPoolExec.execute(runnable);
}

private DecodeBitmapsThreadPool() {
    int coreNum = Runtime.getRuntime().availableProcessors();
    MAX_POOL_SIZE = coreNum * 2;
    mThreadPoolExec = new ThreadPoolExecutor(
            coreNum,
            MAX_POOL_SIZE,
            KEEP_ALIVE,
            TimeUnit.SECONDS,
            workQueue);
}

public static void finish() {
    mInstance.mThreadPoolExec.shutdown();
}

}

So when i start ThreadPool it looks like it get in some kind of a endless loop (according to Logcat) and then i just get OutOfMemoryException. I wonder what i`m i doing wrong, since i cant debug it. I simply want to decode the bitmap in background threads and create base64 representation of those Bitmaps, so i can upload them to the server. P.S. Any ideas how can this be implemented with RxJava2? Thanks in advance!

RadoVidjen
  • 432
  • 7
  • 17

3 Answers3

9

You are not incrementing imageCounter, so it actually is an endless loop.

An enhanced for loop is less error prone:

for (String uri : imageUris) {
    ...
    Bitmap bitmap = BitmapFactory.decodeFile(uri);
    ...
bwt
  • 17,292
  • 1
  • 42
  • 60
2

imageCounter value not changed in while loop,so this condition (imageCounter < imageUris.size()) always true and while loop run infinite times

 while(imageCounter < imageUris.size()) {
        DecodeBitmapsThreadPool.post(new Runnable() {
            @Override
            public void run() {

                Bitmap bitmap = BitmapFactory.decodeFile(imageUris.get(imageCounter));

                mImagesBase64Array.add(bitmapToBase64(bitmap));
            }
        });
    }
0

The issue is that you don't increment the while loop, so the while loop's condition will never be met. You should increment it at the end of code within the while loop like so:

while(imageCounter < imageUris.size()) {
    DecodeBitmapsThreadPool.post(new Runnable() {
        @Override
        public void run() {

            Bitmap bitmap = BitmapFactory.decodeFile(imageUris.get(imageCounter));

            mImagesBase64Array.add(bitmapToBase64(bitmap));
        }
    });

    imageCounter++;
}

Though as mentioned in bwt's answer, an enhanced for loop is generally the best approach for these types of tasks.

Alex Oczkowski
  • 434
  • 6
  • 10