java.lang.OutOfMemoryError occur on the animation

2019-07-31 04:16发布

问题:

What I get from the Developer site is "If in the loading time total size of the animation exceed the value of Virtual heap memory , this error will occur" and For the Solution use BitmapFactory. I tried in the below code :

Now, the question is this, "what are responsible for this error ?" :

  1. Does dimensions of the image are count when the Images load for animation.

    Like : If I have 10 images dimensions( 1100 * 1100 ) and use ARGB_8888 pattern for the image.

  2. Size of images(500KB, 1MB etc ) also matter for this error.

  3. Or Both are responsible for this error.

  4. If I am using more than one animation on a single activity than I change this Activity to another Activity , How to free all memory which I'm using in the previous Activity by AnimationDrawable ?

All suggestion are welcome. thanks

Code

public class AdActivity extends Activity {

ImageView iView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_ad);

    iView = (ImageView) findViewById(R.id.iView);

    //iView.setBackgroundResource(R.drawable.anim); // ( 1 )

    try{ 
             //  (2)
        iView.setImageBitmap(decodeSampleBitmapFromResource(getResources(), R.drawable.anim, 100, 100));

        AnimationDrawable frameAnimation = (AnimationDrawable) iView.getBackground();
        frameAnimation.start();
    }
    catch(Exception e){
    }
}

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {

    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }

    return inSampleSize;
}

public static Bitmap decodeSampleBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {

    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

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

}

Two thing:

  1. Where I mention a comment with ( 1 ), This is simple way to get the animation in a ImageView but in this case the toatal size used is around 44MB when the App is started. 'Run Perfect'

  2. Where I mention ( 2 ) in the try , This is solution which is given by Android developer website here .

i tried no error and size is apporox 11Mb when the App is run but The Animation is not showing in the ImageView.

Please Suggest me what I did wrong ?

回答1:

you can solve your error by 1) increasing your dalvik heap size by android:largeheap="true" in manifest file

2) if your reusing your decoded images then you need to implement Lrucache

3) whenever you decode any image by using decodeSampleBitmapFromResource() then it refences are stored in native heap.it can be cleared by System.gc() to reclaim memory,but we cant depend on this because it is decided by OS when to release it.

4) If u want to clear the native heap you should write a code in NDK



回答2:

Have you checked the value of inSampleSize?

options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

You can save bitmap reference, and recycle bitmap in onPause. You just set one image, how can you see the animation? Refer to AnimationDrawable. this animation consists of multi frames.