prom85
prom85

Reputation: 17798

OutOfMemoryError although I'm down scale the bitmaps

I use small resource images (max 25kb, max 256x256) and load some larger images from the internet with picasso. The picasso loading never failed until now. But the resource image loading does sometimes.

For the resource images I use the code appended (setBitmap), but although I down scale the images, on some devices my app still produces a OutOfMemoryError when calling BitmapFactory.decodeResource. Does anyone have an idea, where to look next?

private static void setBitmap(final ImageView iv, final int resId)
{
    iv.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
    {
        public boolean onPreDraw()
        {
            iv.getViewTreeObserver().removeOnPreDrawListener(this);
            iv.setImageBitmap(decodeSampledBitmapFromResource(iv.getContext().getResources(), resId, iv.getMeasuredWidth(), iv.getMeasuredHeight()));
            return true;
        }
    });
}

private static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int w, int h)
{
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    options.inSampleSize = calculateInSampleSize(options, w, h);

    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

private static int calculateInSampleSize(BitmapFactory.Options options, int w, int h)
{
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > h || width > w)
    {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        while ((halfHeight / inSampleSize) > h && (halfWidth / inSampleSize) > w)
        {
            inSampleSize *= 2;
        }
    }

    L.d(ImageTools.class, "inSampleSize | height | width: " + inSampleSize + " | " + height + " | " + width);

    return inSampleSize;
}

Upvotes: 0

Views: 82

Answers (3)

Misca
Misca

Reputation: 469

If you have a list ImageViews you could implement a cache: http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

Upvotes: 1

Maveňツ
Maveňツ

Reputation: 1

you can request for more memory by using

 android:largeHeap="true"

in the manifest.

also, you can use native memory (NDK & JNI) , so you actually bypass the heap size limitation.

here are some posts made about it:

and here's a library made for it:

happy coding

regards maven

Upvotes: 0

T_V
T_V

Reputation: 17580

You can use android:largeHeap="true" in your manifest as your last option. However I do not recommend this to be use because it can make your app slow.

Upvotes: 0

Related Questions