【发布时间】:2012-01-18 10:38:39
【问题描述】:
我想要达到的目标:
- 减少不再出现在屏幕上的 Activity 的内存使用量,即另一个 Activity 已启动
- 此活动仍位于导航堆栈内的能力,因此我假设我必须在 onStart 内重新构建在 onStop 中被破坏的内容,但不知道当所有视图/按钮都在时如何执行此操作使用 layout.xml 构建。
情况:
我有一个 Android 应用程序,它的图像非常重,但这些图像在许多布局上都是静态的,具有相同的背景、按钮图像、导航标题等。这使我能够非常轻松地构建布局而无需过多接触代码通过在 layout.xml 文件中指定所有 imageView、它们的 src 属性和位置。这很好用,很容易启动和运行,但是现在有很多报告说由于超出内存使用量而强制关闭。
为了清理并允许 gc 删除不在屏幕上的图像和视图,我在 onDestroy 方法中看到了一篇文章(见问题底部),它抓取了一个在布局中保留您的根元素并递归地遍历树删除视图并取消绑定它们。然而,这只是在按下后退按钮时触发并且根据文档不保证。
因此,当我将新活动推入堆栈并且不想清理刚刚离开屏幕的内容时,onDestroy 对我没有帮助。但是使用 onDestroy 方法的好处是入口点从 onCreate 开始,所以视图都是正确构建的。当我在 onStop 中使用此方法时,当我开始一个新活动时,内存得到很好的清理,但是因为我已经对所有视图进行了核对,并且它们是使用 layout.xml 构建的,所以我不明白我需要如何或需要什么如果我破坏 onStop 中的所有内容,则重新构建 onStart,特别是考虑到我从未在代码中创建任何视图,因为它们都是由于 layout.xml 文件而设置的。
主要问题:当我开始一个新的 Activity 时如何清理内存?如果上下文处理正确,gc 是否会清除屏幕外的所有图像视图并自动重新构建它们?
这可以在 onStop 中以某种方式使用吗?
@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();
}
}
【问题讨论】:
标签: android memory-management android-activity crash