android - 活动仍然泄漏,即使实例在onDestroy()方法

时间:2016-09-19 06:44:12

标签: android memory-leaks leakcanary

我在主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;       
    }      
}

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

我正在使用泄漏金丝雀,这就是泄漏 enter image description here

4 个答案:

答案 0 :(得分:1)

尝试使用

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

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

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

答案 1 :(得分:1)

将实例设为WeakReference

private final WeakReference<Activity> navigationActivity;

也不保证会调用onDestroy()。详细了解onDestroy()here

答案 2 :(得分:1)

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

来自Android开发者documentation

  

protected void onDestroy()

     

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

     

注意:不要指望这种方法被称为作为保存的地方   数据!例如,如果活动正在编辑内容中的数据   提供者,这些编辑应该在onPause()或   onSaveInstanceState(Bundle),不在这里。这种方法通常是   实现释放资源,如与线程相关联的线程   活动,以便被破坏的活动不会留下这样的东西   当其余的应用程序仍在运行时。有   系统将简单地杀死活动的主机的情况   进程中没有调用此方法(或任何其他方法),所以它   不应该被用来做那些打算留下来的东西   过程消失后。

答案 3 :(得分:1)

您清除了活动中的参考。但是课程ContactsCompletionView仍然强烈引用您的活动。避免此泄漏的最佳方法是不要公开您活动的链接。
但如果您真的需要这个,可以WeakReference使用Activity。因此,您的方法getNavigationActivity()可能如下所示:

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