Trick
Trick

Reputation: 3849

Android: bitmap size exceeds VM budget (frame by frame)

I get this error all the time. And as I can see, there are a lot of questions already on stackoverflow.com, but sadly, I don't find any answers which will suit me.

I have 60 PNG images (2,5MB all together) which I would like to put it in animation.

I tried with three different ways.

1

mAnimation = new AnimationDrawable();
mAnimation.addFrame((BitmapDrawable)getResources().getDrawable(R.drawable.yawning_00001), FPS_12);  
...
mAnimation.addFrame((BitmapDrawable)getResources().getDrawable(R.drawable.yawning_00063), FPS_12);
mAnimation.start();

2

XML

<animation-list android:oneshot="true">
    <item android:drawable="@drawable/yawning_00001" android:duration="83" />
    ...
    <item android:drawable="@drawable/yawning_00063" android:duration="83" />
 </animation-list>

Java

ImageView img = (ImageView)findViewById(R.id.animation);
img.setBackgroundResource(R.drawable.yawning);
AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();
frameAnimation.start();

3

With class extending ImageView (I will just show important stuff here)

public void loadAnimation(String prefix, int nframes) {
    mBitmapList.clear();
    for (int x = 0; x < nframes; x++) {
        String zeros = "000";
        if (x < 10) {
            zeros += "0";
        }
        String name = prefix + "_" + zeros + x;
        Log.d(TAG, "loading animation frame: " + name);
        int res_id = mContext.getResources().getIdentifier(name, "drawable", mContext.getPackageName());
        d = (BitmapDrawable) mContext.getResources().getDrawable(res_id);
        mBitmapList.add(d.getBitmap());
    }
}

In all cases I get the same error... All some around after 15 picture loads.

E/AndroidRuntime(1591): java.lang.OutOfMemoryError: bitmap size exceeds VM budget

I am begging to wonder if this is frame animations are even possible in Android.

Does anybody maybe have a alternative to frame by frame animation? If yes, please link to any showcase.

Upvotes: 0

Views: 1396

Answers (2)

Nguyen  Minh Binh
Nguyen Minh Binh

Reputation: 24423

Sometimes, The memory leak come from some where which isn't the line of code show in stack trace. I think you should read below article carefully then check your own code to omit some special issue, such as:

  • Do not keep long-lived references to a context-activity (a reference to an activity should have the same life cycle as the activity itself)
  • Try using the context-application instead of a context-activity
  • Avoid non-static inner classes in an activity if you don't control their life cycle, use a static inner class and make a weak reference to the activity inside. The solution to this issue is to use a static inner class with a WeakReference to the outer class, as done in ViewRoot and its W inner class for instance**

Article

EDIT: You also should check these:

  • Call recycle() to remove unused bitmap

  • use sampleSize > 1 to reduce bitmap size.

Bitmap.createBitmap(width, height, new BitmapFactory.Options().inSampleSize=4)

Upvotes: 0

Yahel
Yahel

Reputation: 8550

You will need to recycle your images in some way because you won't have enough memory ever for 60 images.

You think your images are 2,5 meg all together but this the compressed png version of your files.

If you want to know how much memory you are using with your files when uncompressed in bitmap format in memory just do : width*height*number of images*bytes per pixel....Then you'll know why you crash :D

AnimationDrawable are not meant for that kind of heavy usage. You should start looking at SurfaceViews and then you'll be free to implement whatever memory management method you want to use to display your animation.

http://developer.android.com/reference/android/view/SurfaceView.html

Good luck.

Upvotes: 4

Related Questions