onStop(或屏幕外) Activity 的Android内存管理

标签 android memory-management android-activity crash

我要实现的目标:

  • 减少不再显示在屏幕上的 Activity 的内存使用,即另一个 Activity 已经开始
  • 这个 Activity 仍然在导航堆栈中的能力,所以我假设我必须重新构建在 onStop 中被破坏的东西,在 onStart 中,但不确定当所有 View /按钮都被破坏时如何做到这一点使用 layout.xml 构建。

情况:

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

在尝试清理并允许 gc 删除不在屏幕上的图像和 View 时,我看到一篇文章(请参阅问题底部)建议在 onDestroy 方法中,捕获一个在布局中保留你的根元素并递归地遍历树删除 View 并解除它们的绑定(bind)。然而,这只会在按下后退按钮时触发并且根据文档不能保证

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

主要问题:如何在启动新 Activity 时清理内存?如果上下文得到正确处理,gc 是否会清理屏幕外的所有 ImageView 并自动重新构建它们?

这可以在 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();
    }
}

最佳答案

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

乙) 使用 onStart()/onStop() 将在 Activity 可见时进行分配,在 Activity 不可见时取消分配。

使用 A) 或 B)。不要混合使用它们,否则您会过于频繁地分配或取消分配。

在您的情况下,我会将所有内容从 onCreate() 移至 onStart(),并将所有内容从 onDestroy() 移至 onStop()。

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

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

关于onStop(或屏幕外) Activity 的Android内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8474257/

相关文章:

android - 为什么我看不到使用此 Activity 的 ProgressDialog?

ios - 为什么 weak for property 和 __weak for instance variable 表现不同

java - Android:每个 View 的不同 Java 文件

java - Android ListView 只显示最新的项目

android - 在 Android 上使用 RNCryptor

c - 将链表实现与 malloc 函数分离

.net - 是什么触发了第二代垃圾回收?

Android,在恢复时动态创建的 editTexts 的 id 和 View 的清晰文本值

android - Adobe AIR CameraRoll 无法在 Android 6.0 上选择照片

java - 上传图片到mysql服务器