<?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"
>
...
然后,在您的活动的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()
方法会递归地遍历视图树,并执行以下操作:
听起来你的应用存在内存泄漏问题。这个问题并不在于处理多张图片,而是当你的activity被销毁时,你的图片没有得到释放。
没有看到你的代码很难确定原因。然而,这篇文章提供了一些可能有用的提示:
http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html
特别地,使用静态变量可能会使情况变得更糟,而不是变得更好。你可能需要添加代码,在应用程序重新绘制时删除回调 - 但同样,在这里提供的信息不足以确定是否需要这样做。
Bitmap
对象设置为null
(或设置另一个值)之前使用本地方法Bitmap.recycle()
。例如:public final void setMyBitmap(Bitmap bitmap) {
if (this.myBitmap != null) {
this.myBitmap.recycle();
}
this.myBitmap = bitmap;
}
然后你可以这样更改myBitmap
,而无需调用System.gc()
:
setMyBitmap(null);
setMyBitmap(anotherBitmap);
以下几点对我帮助很大。还可能有其他要点,但这些非常关键:
我曾经遇到过完全相同的问题。经过一番测试,我发现这个错误是由于大图缩放引起的。我减小了图像的缩放比例,问题就消失了。
另外,我先尝试了不缩放图像而只是减小图像尺寸的方法,但并没有解决这个错误。
<activity android:name=".main.MainActivity"
android:label="mainActivity"
android:configChanges="orientation|keyboardHidden|navigation">
</activity>
我提供的第一个解决方案已经将OOM错误的频率降低到了很低的水平。但是,它并没有完全解决问题。接下来我将提出第二个解决方案:
根据OOM的详细信息,我使用了太多的运行时内存。因此,我在我的项目中的~/res/drawable文件夹中减小了图片的大小。例如,一个分辨率为128X128的过度合格的图片可以被调整为64x64,这也适用于我的应用程序。在我对大量的图片进行了这样的操作之后,OOM错误不再出现。
在高效加载大型位图课程中讨论的BitmapFactory.decode*方法,如果源数据是从磁盘或网络位置(或者任何非内存来源)读取的,则不应在主UI线程上执行。加载此数据所需的时间是不可预测的,并且取决于各种因素(从磁盘或网络读取的速度,图像大小,CPU功率等)。如果其中一个任务阻塞了UI线程,则系统会将您的应用标记为无响应,并且用户可以选择关闭它(有关更多信息,请参见设计响应性)。