简体   繁体   English

动画导致内存不足异常

[英]Animation causing out of memory exception

My application provides an outofmemory exception when an animation starts to play.当动画开始播放时,我的应用程序提供了outofmemory异常。 What can I do?我能做些什么? The images in animation combined have a size of 512kb, that's 10 images.动画中的图像组合大小为 512kb,即 10 张图像。

My activity class is button_anime .我的活动课程是button_anime

 public class Button_Anime extends Activity{

private static int SPLASH_TIME_OUT = 500;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash_about);
    ImageView loading =(ImageView) findViewById(R.id.iVArcRail_2);
    loading.setBackgroundResource(R.drawable.about_button_anime);
    AnimationDrawable load =(AnimationDrawable)loading.getBackground();
    load.start();
    new Handler().postDelayed(new Runnable() {
               
        @Override
        public void run() {
               Intent i = new Intent(Button_Anime.this, Home.class); 
            startActivity(i);
            finish();
        }
    }, SPLASH_TIME_OUT);
  }
 }

My activity_splash_about.xml我的activity_splash_about.xml

  <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/withoutlogo" >

<ImageView
    android:id="@+id/imageView1"
    android:layout_width="wrap_content"
    android:layout_height="70dp"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginBottom="10dp"
    android:layout_marginTop="10dp"
    android:background="@drawable/logoline" />

<ImageView
    android:id="@+id/iVArcRail_2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/imageView1"/>
 </RelativeLayout>

This is the animation file.这是动画文件。 about_button_anime

  <?xml version="1.0" encoding="utf-8"?>
  <animation-list xmlns:android="http://schemas.android.com/apk/res/android" 
  android:oneshot="false" >
  <item
      android:drawable="@drawable/ab1"
      android:duration="50"/>
  <item
      android:drawable="@drawable/ab2"
      android:duration="50"/>
  <item
      android:drawable="@drawable/ab3"
      android:duration="50"/>
  <item
      android:drawable="@drawable/ab4"
      android:duration="50"/>
  <item
      android:drawable="@drawable/ab5"
      android:duration="50"/>
  <item
      android:drawable="@drawable/ab6"
      android:duration="50"/>
  <item
      android:drawable="@drawable/ab7"
      android:duration="50"/>
  <item
      android:drawable="@drawable/ab8"
      android:duration="50"/>
  <item
      android:drawable="@drawable/ab9"
      android:duration="50"/>
  <item
      android:drawable="@drawable/ab10"
      android:duration="50"/>
  
  </animation-list>

And this is my log cat.这是我的原木猫。

 FATAL EXCEPTION: main
 Process: com.quinoid.thomasinternational, PID: 1514
 java.lang.OutOfMemoryError
 at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
 at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:587)
 at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:422)
 at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:840)
 at android.content.res.Resources.loadDrawable(Resources.java:2110)
 at android.content.res.Resources.getDrawable(Resources.java:700)
 at android.graphics.drawable.AnimationDrawable.inflate(AnimationDrawable.java:282)
 at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:937)
 at android.graphics.drawable.Drawable.createFromXml(Drawable.java:877)
 at android.content.res.Resources.loadDrawable(Resources.java:2092)
 at android.content.res.Resources.getDrawable(Resources.java:700)
 at android.view.View.setBackgroundResource(View.java:15303)
 at com.quinoid.thomasinternational.Button_Anime.onCreate(Button_Anime.java:19)
 at android.app.Activity.performCreate(Activity.java:5231)
 at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
 at android.app.ActivityThread.access$800(ActivityThread.java:135)
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
 at android.os.Handler.dispatchMessage(Handler.java:102)
 at android.os.Looper.loop(Looper.java:136)
 at android.app.ActivityThread.main(ActivityThread.java:5017)
 at java.lang.reflect.Method.invokeNative(Native Method)
 at java.lang.reflect.Method.invoke(Method.java:515)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
 at dalvik.system.NativeStart.main(Native Method)

How can I get this animation running?我怎样才能让这个动画运行?

I have already provided largeHeap="true" .我已经提供了largeHeap="true"

This will work like charm,这会像魅力一样起作用,

Make sure you put your images in the asset folder.确保将图像放在资产文件夹中。

public class AnimationActivily extends Activity {

private Bitmap log_imgs[];
private Bitmap tempBitmap;
private Handler uiHandler;
private ImageView logo_view;
int img_cnt = 1;
protected int _splashTime = 91;
Thread splashTread;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.activity_animation_activily);
    logo_view = (ImageView) findViewById(R.id.logo_view);
    log_imgs = new Bitmap[91];
    for (int i = 1; i <= 90; i++) {
        get_Images_Assest(i, "logo_pngs");
    }
    logo_view.setImageBitmap(log_imgs[70]);
    uiHandler = new Handler();
    // thread for displaying the SplashScreen
    splashTread = new Thread() {
        @Override
        public void run() {
            try {
                while (img_cnt < _splashTime) {
                    sleep(30);
                    if (img_cnt <= 90)
                        update_view(img_cnt);
                    img_cnt++;

                }
            } catch (InterruptedException e) {
                // do nothing
            } finally {

                Intent i = new Intent(AnimationActivily.this,
                        MainActivity.class);
                i.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                startActivity(i);
                AnimationActivily.this.finish();
                // overridePendingTransition(R.anim.slide_in,
                // R.anim.slide_out);
                // *** Put this in another
                // Activity***//overridePendingTransition(R.anim.slide_in,
                // R.anim.slide_out);
            }
        }
    };
    splashTread.start();

}

public Bitmap tempImg;

private void get_Images_Assest(int cnt, String folder_name) {
    try {

        InputStream is = getAssets().open(
                folder_name + "/" + "logo" + cnt + ".png");
        if (tempImg != null) {
            tempImg = null;
        }
        tempImg = BitmapFactory.decodeStream(is);
        // tempBitmap = Bitmap.createScaledBitmap(tempImg,
        // tempImg.getWidth() * 2, tempImg.getHeight() * 2, true);
        log_imgs[cnt] = tempImg;
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void update_view(final int cnt) {
    uiHandler.post(new Runnable() {
        public void run() {
            try {
                logo_view.setImageBitmap(log_imgs[cnt]);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

}

public void onBackPressed() {
}

public void onDestroy() {
    super.onDestroy();

    for (int i = 1; i <= 90; i++) {
        log_imgs[i].recycle();
    }
    log_imgs = null;
    splashTread = null;
}
}

I had the same problem, so I created a class to avoid from OutOfMemoryError.我有同样的问题,所以我创建了一个类来避免 OutOfMemoryError。 Android loads all the drawables at once, so animation with many frames causes this error. Android 一次加载所有可绘制对象,因此具有许多帧的动画会导致此错误。

FasterAnimationsContainer更快的动画容器

FasterAnimationsContainer will help you to avoid from OutOfMemoryError. FasterAnimationsContainer 将帮助您避免 OutOfMemoryError。 This class loads & sets and releases an image on background thread.此类在后台线程上加载、设置和释放图像。

here's link这是链接

Easy to implement易于实施

public class ExampleActivity extends Activity {

FasterAnimationsContainer mFasterAnimationsContainer;
private static final int[] IMAGE_RESOURCES = { R.drawable.anim_1,
        R.drawable.anim_2, R.drawable.anim_3, R.drawable.anim_4,
        R.drawable.anim_5, R.drawable.anim_6, R.drawable.anim_7,
        R.drawable.anim_8 };

private static final int ANIMATION_INTERVAL = 500;// 200ms

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_example);
    ImageView imageView = (ImageView) findViewById(R.id.imageview);
    mFasterAnimationsContainer = FasterAnimationsContainer
            .getInstance(imageView);
    mFasterAnimationsContainer.addAllFrames(IMAGE_RESOURCES,
            ANIMATION_INTERVAL);
    mFasterAnimationsContainer.start();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mFasterAnimationsContainer.stop();
}
}

I had a similar problem with my background animation on devices with low memory.我在内存不足的设备上的背景动画也有类似的问题。 The way I managed to fix it was by instantiating the animation programmatically instead of through the xml animation-list.我设法修复它的方法是通过编程方式实例化动画,而不是通过 xml 动画列表。 I no longer run into out of memory issues with this view.我不再遇到此视图的内存不足问题。

    AnimationDrawable animationDrawable = new AnimationDrawable();
    animationDrawable.setOneShot(false); // True = only once, False = continuous

    int[] resources = {R.drawable.ticket_background_animation_1, R.drawable.ticket_background_animation_2, R.drawable.ticket_background_animation_3};

    int duration = 30;

    for (int resource : resources) {
        animationDrawable.addFrame(ContextCompat.getDrawable(context, resource), duration);
    }

    relativeLayout.setBackground(animationDrawable);
    animationDrawable.start();

It's of course also very important to remember to stop the animation again in onDestroy() !当然,记住在onDestroy()中再次停止动画也很重要!

    ((AnimationDrawable) relativeLayout.getBackground()).stop();
    // Sets background to null to make sure the animation is garbage collected
    relativeLayout.setBackground(null);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM