【问题标题】:android - Activity still leaks even instance is set to null in onDestroy() methodandroid - 即使在 onDestroy() 方法中将实例设置为空,活动仍然会泄漏
【发布时间】:2016-09-19 06:44:12
【问题描述】:

我在主 Activity (NavigationActivity) 中遇到内存泄漏问题

public static NavigationActivity navigationActivity;

public static NavigationActivity getNavigationActivity() {
    return navigationActivity;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_navigation);

    navigationActivity = NavigationActivity.this;

}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (navigationActivity != null) {
        navigationActivity = null;       
    }      
}

它在哪里泄漏?我该如何解决?任何帮助,将不胜感激。非常感谢。

我正在使用泄漏金丝雀,这是泄漏

【问题讨论】:

  • 我查看了您的个人资料,发现您根本不接受答案。您应该为未来的读者这样做,以便他们知道哪个答案是正确的。出于这个原因投反对票
  • 你能在leakCanary截图中打开NavigationActivity (+) stacktree吗?这个 navigationActivity 类是什么?

标签: android memory-leaks leakcanary


【解决方案1】:

尝试使用

@Override
protected void onStop() {
    super.onStop();
    navigationActivity = null;
}

但是使用 Activity 的静态引用是非常糟糕的做法,不要这样做。

在大多数情况下,您可以使用 activity.this 引用或类似 getActivity() 的方法。

【讨论】:

    【解决方案2】:

    将实例设为WeakReference

    private final WeakReference<Activity> navigationActivity;
    

    还不能保证调用onDestroy()。阅读更多关于 onDestroy() here.

    【讨论】:

      【解决方案3】:

      您应该在onStop method 中将活动实例设置为null,因为onDestroy 可能不会被调用。

      来自Android开发者documentation

      protected void onDestroy ()

      在 API 级别 1 中添加 在活动开始之前执行任何最终清理 被摧毁。这可能是因为活动正在结束 (有人叫finish()就可以了,或者因为系统暂时 销毁该活动实例以节省空间。你可以 用 isFinishing() 方法区分这两种情况。

      注意:不要指望调用此方法作为保存位置 数据!例如,如果活动正在编辑内容中的数据 提供者,这些编辑应该在 onPause() 或 onSaveInstanceState(Bundle),不在这里。这种方法通常 实现释放资源,如与 活动,以便被破坏的活动不会留下这样的东西 在其应用程序的其余部分仍在运行时。有 系统将简单地终止活动托管的情况 处理而不在其中调用此方法(或任何其他方法),因此它 不应该被用来做打算留在身边的事情 进程结束后。

      【讨论】:

      • 相反,我会说清除对象类似于释放资源,并且它是清理我们不再需要的对象的好地方。
      【解决方案4】:

      您清除了 Activity 中的引用。但是ContactsCompletionView 类仍然对您的活动有很强的参考意义。避免这种泄漏的最佳方法是不要公开指向您的活动的链接。
      但是如果你真的需要这个,你可以使用WeakReference 到你的Activity。所以你的方法getNavigationActivity() 可能看起来像这样:

      public static WeakReference<NavigationActivity> navigationActivityRef;
      {
          public static WeakReference<NavigationActivity> getNavigationActivity() {
            if(navigationActivityRef == null) {
                navigationActivityRef = new WeakReference<>(this);
            }
            return navigationActivityRef;
      }     
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-23
        • 2014-02-15
        • 1970-01-01
        • 2020-07-21
        • 1970-01-01
        相关资源
        最近更新 更多