用于onStop(或屏幕外)活动的Android内存管理

时间:2011-12-12 12:23:01

标签: android memory-management android-activity crash

我想要实现的目标:

  • 减少不再在屏幕上显示的活动的内存使用情况,即已启动其他活动
  • 此活动仍然在导航堆栈中的能力,所以我假设我必须在onStart中重新构建onStop中被破坏的内容,但不知道如何在所有视图/按钮是使用layout.xml构建。

情况:

我有一个非常重要的Android应用程序,但这些图像在许多布局上是静态的,具有相同的背景,按钮图像,导航标题等。这使我很容易构建布局而不会过多地触及代码通过在layout.xml文件中指定所有imageView,src属性和位置。这很好用,很容易启动和运行,但是现在有很多关于由于超出内存使用而关闭强制的报告。

所以在尝试清理并允许gc删除不在屏幕上的图像和视图时,我遇到了一篇文章(参见问题的底部),在onDestroy方法中建议,抓住一个在布局中保存您的根元素,并递归地遍历树,删除视图并解除它们的绑定。但是,当按下后退按钮时,这只会被解雇并且无法保证根据文档

因此,当我将新活动推入堆栈并且不想清理刚离开屏幕的内容时,onDestroy对我没有帮助。但是使用onDestroy方法的好处是入口点从onCreate开始,因此视图都是正确构建的。当我在onStop中使用这个方法时,当我开始一个新的活动时,内存得到很好的清理,但是因为我已经修改了所有的视图,并且它们是使用layout.xml构建的,所以我不明白我需要怎样或者我需要什么如果我在onStop中销毁所有内容,请重新构建onStart,特别是考虑到我从未在代码中创建任何视图,因为它们都是由于layout.xml文件而设置的。

主要问题:如何在开始新活动时清理内存?如果正确处理了上下文,那么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();
    }
}

2 个答案:

答案 0 :(得分:2)

A) 使用onCreate()/ onDestroy()将在活动进入堆栈时进行分配,并在从堆栈中弹出活动时取消分配。

B) 使用onStart()/ onStop()将在活动可见时分配,并在活动不可见时取消分配。

使用A)或B)。不要混淆它们,否则你会经常分配或解除分配。

在你的情况下,我会将所有内容从onCreate()移动到onStart(),以及从onDestroy()到onStop()的所有内容。

另外,还要考虑在onStop()中使用this.setContentView(null)或this.setContentView(new View(this)),以确保可以对旧视图进行垃圾回收:

  @Override
  protected void onStop() {
    super.onStop();
    View root = findViewById(R.id.RootView);
    setContentView(new View(this)) 
    unbindDrawables(root);
    System.gc();
  }

答案 1 :(得分:1)

我认为任何活动回调都不是理想的做法。你的活动总是会变得非常缓慢。

如果可以,我想你宁愿坚持图像,但如果系统需要资源你想放弃。如果这个(缓存)正是你所看到的WeakReference是你的男人。请参阅此excellent article,以帮助您决定/理解。

此外,我不认为android会让我们的开发人员担心布局文件生成的视图何时被gc'd。只要您没有强烈引用视图,就应该没问题。