Java – Android BitmapFactory.decodeResource takes up too much memory

Android BitmapFactory.decodeResource takes up too much memory… here is a solution to the problem.

Android BitmapFactory.decodeResource takes up too much memory

I have a problem with loading bitmaps from resources. My code:

public void onClick(View view) {
    if (mainButton == view) {
        Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.test);
    }
}

The test.jpg image resolution is 3288 x 4936 pixels. It is jpeg (3.9MB/48.7MB uncompressed). While this feature works (on my Nexus 7 2013 device), the following exception occurs:

java.lang.OutOfMemoryError: Failed to allocate a 259673100 byte allocation with 5222644 free bytes and 184MB until OOM
        at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
        at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
        at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
        at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
        at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:467)
        at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:497)
        at pl.jaskol.androidtest.MainActivity.onClick(MainActivity.java:50)
        at android.view.View.performClick(View.java:4756)
        at android.view.View$PerformClick.run(View.java:19749)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

Why does an application try to allocate up to 248MB of space?
I wrote a similar app in Qt for Android with the same image in the resource and it works fine.

Edit:

  1. I can’t resize it.

  2. It’s a very simple app, like Hello World. It does nothing but load bitmaps from resources.

Edit 2:

Jim’s solution worked for me. But there is one more problem. When the bitmap is loaded, it is 4 times too large (2 times high and 2 times wide). I tried various images, including new ones created in Pinta or Gimp.

Solution

You can use android:largeHeap="true" on the application label in the AndroidManifest.xml file to exceed the 64MB limit. This does not apply to pre 3.0 devices.

This may solve your problem immediately. If that’s not enough, you can load the bitmap using native code, where your heap limit is the entire memory on the device. NDK involves more, so try the above solutions first.

Related Problems and Solutions