实际上我在我的应用程序中面临内存不足错误。:(问题是我一直在我的应用程序中使用活动数量,现在我无法转向另一种方法..:(所以在翻转 27 或29 个活动我在 setContentView() 上的 30 个活动上遇到 OOM 错误。在我的所有 XML 文件中,我一直在使用 AbsoluteLayout 设置背景图像,每个布局都有一个主页。在每个布局中,我都设置了 4 到 5 个背景按钮image. 现在每个按钮都设置有声音的图像。
3 回答
我发现开发 Android 应用程序的最常见错误之一是“java.lang.OutOfMemoryError: Bitmap Size Exceeds VM Budget”错误。我在更改方向后使用大量位图的活动上经常发现此错误:活动被销毁,再次创建,布局从 XML 中“膨胀”,消耗了位图可用的 VM 内存。
垃圾收集器未正确释放先前活动布局上的位图,因为它们已交叉引用其活动。经过多次实验,我找到了一个很好的解决这个问题的方法。
首先,在 XML 布局的父视图上设置“id”属性:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/RootView"
>
...
然后,在 Activity 的 onDestroy() 方法上,调用 unbindDrawables() 方法,将引用传递给父视图,然后执行 System.gc()
@Override
protected void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.RootView));
System.gc();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
这个 unbindDrawables() 方法递归地探索视图树并且:
Removes callbacks on all the background drawables
Removes childs on every viewgroup
这个解决方案对我有用
我建议使用system.gc()
并且finish();
每次跳转另一个活动它会清除您使用的资源并释放它。好的,那么您的应用程序中不会发生内存不足错误。这是工作试试这个。
祝你好运
使用此链接并获得更好的解决方案
我一直在没有大量 RAM (HTC Wildfire) 的 Gingerbread (2.3.7) 设备上解决这个问题。旋转设备几次后,应用程序崩溃:
E/AndroidRuntime( 4805): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
E/AndroidRuntime( 4805): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
E/AndroidRuntime( 4805): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:460)
E/AndroidRuntime( 4805): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336)
E/AndroidRuntime( 4805): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
E/AndroidRuntime( 4805): at android.content.res.Resources.loadDrawable(Resources.java:1785)
E/AndroidRuntime( 4805): at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
E/AndroidRuntime( 4805): at android.widget.ImageView.<init>(ImageView.java:118)
E/AndroidRuntime( 4805): at android.widget.ImageView.<init>(ImageView.java:108)
E/AndroidRuntime( 4805): ... 26 more
旋转的布局非常简单,RelativeLayout
有几个ImageView
孩子,其中一个有一个相对较大(文件大小)的图像作为屏幕一部分的背景。
我尝试实施@AndroidUsers 的解决方案,但这并没有解决我的问题。通过更多的工作,我发现我保存背景图像的 ImageView 没有正确释放它的内存,所以我在 unbindDrawables 方法中添加了另一个检查。我还通过一个额外的参数捆绑在 system.gc() 调用中,因此不能错过:
public static void unbindDrawables(View view, boolean runGC) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ImageView) {
((ImageView) view).setImageBitmap(null);
((ImageView) view).setImageDrawable(null);
}
else if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i), false);
}
((ViewGroup) view).removeAllViews();
}
if(runGC) {
System.gc();
}
}
在我的测试中,您将 Bitmap 或 Drawable 中的哪一个设置为 null 似乎并不重要,但我认为两者都不会受到伤害。