【问题标题】:java.lang.OutOfMemoryError occur on the animation Loading?java.lang.OutOfMemoryError 发生在动画加载?
【发布时间】:2026-01-05 17:05:01
【问题描述】:

我从开发者网站得到的是“如果在加载时动画的总大小超过虚拟堆内存的值,就​​会发生这个错误”,对于解决方案,请使用BitmapFactory。我试过下面的代码:

现在的问题是,“什么是造成这个错误的原因?”

  1. 图片加载动画时是否计算图片尺寸。

    喜欢:如果我有 10 个图像尺寸(1100 * 1100)并使用 ARGB_8888 模式作为图像。

  2. 图像大小(500KB、1MB 等)也与此错误有关。

  3. 或者两者都对这个错误负责。

  4. 如果我在单个 Activity 上使用多个动画而不是 change this Activity to another Activity,如何通过 AnimationDrawable 释放我在上一个 Activity 中使用的所有内存?

欢迎所有建议。谢谢

代码

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);
}

}

两件事:

  1. 我提到 (1) 的注释,这是在 ImageView 中获取动画的简单方法,但在这种情况下,应用启动时使用的总大小约为 44MB。 '完美运行'

  2. 我在尝试中提到(2),这是Android开发者网站here给出的解决方案。

我试过没有错误,当应用程序运行时大小约为 11Mb,但动画没有显示在 ImageView 中。

请告诉我我做错了什么?

【问题讨论】:

标签: android android-animation android-memory animationdrawable


【解决方案1】:

您可以通过 1) 在清单文件中通过 android:largeheap="true" 增加 dalvik 堆大小来解决您的错误

2)如果你重用你的解码图像,那么你需要实现 Lrucache

3) 每当您使用 decodeSampleBitmapFromResource() 解码任何图像时,它的引用都存储在本机堆中。它可以由 System.gc() 清除以回收内存,但我们不能依赖它,因为它是由操作系统决定的什么时候发布。

4) 如果你想清除本机堆,你应该在 NDK 中编写代码

【讨论】:

  • 增加堆大小......这不是一个好主意......正如我所研究的那样
  • 我有点困惑,因为我需要用动画和通过 xml 文件处理的所有图像来完成这一切。所以我想知道,我应该通过编程方式添加所有动画图像......还是我们可以做的其他事情来实现这一目标
【解决方案2】:

你检查过 inSampleSize 的值吗?

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

您可以保存位图参考,并在onPause 中回收位图。 你只是设置了一个图像,你怎么能看到动画?请参阅AnimationDrawable。此动画由多帧组成。

【讨论】:

  • 我试过了,我知道这是不可能的,它只适用于单个图像,所以对于动画..我需要以编程方式为动画添加 Frame 还是其他什么?
  • 如果没有在xml中配置框架,则必须通过代码动态添加。你试过使用'public void addFrame(Drawable frame, int duration)'吗?添加超过 1 帧以检查效果。
  • 嗯,如果我不能从中得到任何解决方案,我会在最后尝试这个。如果可以以上查询。请先阅读到四点。也许,你会明白我真正需要什么。谢谢
最近更新 更多