我在 Android 上开发了一个使用大量图像的应用程序。
该应用程序运行一次,填充屏幕上的信息(Layouts
, Listviews
, Textviews
, ImageViews
等),用户读取信息。
没有动画,没有特效或者任何可以填满记忆的东西。
有时绘图可能会改变。有些是android资源,有些是保存在SDCARD文件夹中的文件。
然后用户退出(onDestroy
方法被执行并且应用程序由虚拟机保留在内存中),然后在某个时刻用户再次输入。
每次用户进入应用程序时,我都可以看到内存越来越多,直到用户获得java.lang.OutOfMemoryError
.
那么处理许多图像的最佳/正确方法是什么?
我应该将它们放在静态方法中,这样它们就不会一直加载吗?
我是否必须以特殊方式清理布局或布局中使用的图像?
我发现开发 Android 应用程序时最常见的错误之一是“java.lang.OutOfMemoryError:位图大小超出 VM 预算”错误。在更改方向后,我经常在使用大量位图的活动中发现此错误:活动被销毁,再次创建,并且布局因消耗可用于位图的 VM 内存的 XML 而“膨胀”。
垃圾收集器无法正确取消分配先前活动布局上的位图,因为它们交叉引用了其活动。经过多次实验,我找到了一个很好的解决这个问题的方法。
首先,在 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"
>
...
然后,在onDestroy()
您的 Activity 的方法,调用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();
}
}
This unbindDrawables()
方法递归地探索视图树并且:
- 删除所有背景可绘制对象上的回调
- 删除每个视图组上的子项
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)