1

I'm receiving an OutOfMemoryExeption in my Android application and I cannot find out, after Googling for hours. Hopefully someone can help my.

I have a listview, and in this function:

public View getView(int position, View convertView, ViewGroup parent) {
...

    Bitmap image = getBitmapFromMemCache(imageFilePath);
    if (image == null) {
        addBitmapToMemoryCache(imageFilePath, BitmapFactory.decodeFile(imageFilePath));
        image = getBitmapFromMemCache(imageFilePath);
    } 

    if (((WallActivity) context).isFavorite(position)) {
        Drawable drawable = new BitmapDrawable(context.getResources(), image);
        if (android.os.Build.VERSION.SDK_INT < 16) {
            convertView.setBackgroundDrawable(drawable);
        } else {
            convertView.setBackground(drawable);
        }
    }
...
}

The error occurs on this line:

Drawable drawable = new BitmapDrawable(context.getResources(), image);

I cannot use downscaleoptions, because my image is already downscaled on the device storage. These are the logs:

java.lang.OutOfMemoryError: (Heap Size=131079KB, Allocated=129644KB)
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:658)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:347)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:430)
at com.application.app.model.adapters.WallAdapter.setView(WallAdapter.java:252)
at com.application.app.model.adapters.WallAdapter.getView(WallAdapter.java:211)
at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:220)
at android.widget.AbsListView.obtainView(AbsListView.java:2334)
at android.widget.ListView.makeAndAddView(ListView.java:1937)
at android.widget.ListView.fillDown(ListView.java:789)
at android.widget.ListView.fillGap(ListView.java:753)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5259)
at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4413)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:734)
at android.view.Choreographer.doCallbacks(Choreographer.java:560)
at android.view.Choreographer.doFrame(Choreographer.java:527)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:719)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5454)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:796)
at dalvik.system.NativeStart.main(Native Method)
BenMorel
  • 34,448
  • 50
  • 182
  • 322
John
  • 124
  • 8
  • Did you already read through the relevant documentation here http://developer.android.com/training/displaying-bitmaps/index.html for any clues on what you could improve? Usually, I'd expect "Bitmap size exceeds VM budget" with the OOM exception when you are trying to decode an image too large for the available memory, so maybe there is memory going to waste elsewhere and it fails even before the actual decoding process? – bgse Feb 25 '14 at 22:54
  • Thanks for your reply, yes I looked into that. How can I detect where memory is going to waste? – John Feb 25 '14 at 22:55
  • Normally, you should see some memory management related messages in your logcat. I'd keep an eye on these while debugging your application and see if something fishy sticks out. Maybe also check out some pointers in this thread: http://stackoverflow.com/questions/1147172/what-android-tools-and-methods-work-best-to-find-memory-resource-leaks – bgse Feb 25 '14 at 23:00
  • Is it possible that the Bitmaps wich are created everytime getView is called, won't be released? I cannot find any other big allocations (via DDMS) – John Feb 25 '14 at 23:17
  • I fixed this finaly by moving the bitmap related code to an asynctask – John Feb 26 '14 at 14:49

1 Answers1

1

I fixed this finaly by moving the bitmap related code to an asynctask

    @Override
    protected Bitmap doInBackground(String... params) {
        imageFilePath = params[0];
        Bitmap image = getBitmapFromMemCache(imageFilePath);
        if (image == null) {
            try {
                addBitmapToMemoryCache(imageFilePath, BitmapFactory.decodeFile(imageFilePath));
                image = getBitmapFromMemCache(imageFilePath);

            } catch (OutOfMemoryError e) {
                e.printStackTrace();
            }
        }
        return image;
    }

    @Override
    protected void onPostExecute(Bitmap bm) {
        if (bm != null) {
            Drawable drawable = new BitmapDrawable(context.getResources(), bm);
            if (android.os.Build.VERSION.SDK_INT < 16) {
                convertView.setBackgroundDrawable(drawable);
            } else {
                convertView.setBackground(drawable);
            }
        } else {
            convertView.setBackgroundColor(Color.BLACK);
        }
    }
John
  • 124
  • 8