Android 内存泄漏检测工具LeakCanary基本使用总结

一、前言

在项目开发过程中,性能检测分析是必不可少的一个环节,选择一款好的对口的工具能让我们事半功倍。LeakCanary是一款Square公司提供的检测内存泄漏的工具,LeakCanary使用起来非常方便,下面我们就来看下其基本用法,当然也可以直接查看官方文档

二、基本使用

我们首先在gradle中添加LeakCanary依赖,注意如果android studio3.0版本以后则需要使用debugImplementation这种依赖方式

    debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.4'
    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'

随后在我们的Application类中,开始启动我们的LeakCanary

public class MyApplication extends Application {

    @Override public void onCreate() {
        super.onCreate();
        if (LeakCanary.isInAnalyzerProcess(this)) {
            // This process is dedicated to LeakCanary for heap analysis.
            // You should not init your app in this process.
            return;
        }
        LeakCanary.install(this);
    }
}

这就欧了,是不是非常方便,当LeakCanary在调试版本中检测到你的Activity发生内存泄漏时,你的通知栏就会收到其通知提醒。为了测试一下上面的几行代码是否就真的能实现我们的需求,我写了一段内存泄漏的代码,请叫我写bug小能手[笑哭]

public class CommentUtils {
    public static CommentUtils utils;
    private Context context;

    public static CommentUtils getUtils(Context context) {
       if(utils == null){
            synchronized (CommentUtils.class) {
                if(utils == null){
                    // 因为静态utils变量的生命周期等同程序生命周期
                    // 所以当utils持有activity的context时,会使activity始终存在着utils的强引用,导致该activity无法被销毁
                    // 解决办法1.使用context.getApplicationContext(),2.弱引用context
                    utils = new CommentUtils(context);
                }
            }
        }
        return utils;
    }

    private CommentUtils(Context context) {
        this.context = context;
    }
}

随后在我们的类中,使用该内存泄漏的代码,非常简单的代码

public class MonitoringActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_monitoring);
        CommentUtils utils = CommentUtils.getUtils(this);
    }
}

好了,接下来我们横竖屏切换,让我们的MonitoringActivity类执行onDestroy销毁掉,等待几秒钟(我测试了HUAWEI和OPPO,两个手机的等待时间不同),随后我们的通知栏就会出现通知:

这里写图片描述

当你的系统在6.0以上,LeakCanary首先会发送一条通知告知你没有权限,点击该通知条允许app获得权限,随后就能够正常接收内存泄漏的通知,点击并可以查看当前泄漏详情:

这里写图片描述

好了,Activity的内存泄漏检测到这里就介绍完了,但是如果你需要检测Fragment,这样做其实还是不够的,不过也很简单,我们来简单看一下,这是我们的Application类,我们需要一个RefWatcher类来监听我们的Fragment

public class MyApplication extends Application {

    public static RefWatcher getRefWatcher(Context context) {
        MyApplication application = (MyApplication) context.getApplicationContext();
        return application.refWatcher;
    }
    //程序运行的时候会创建一个Application 对象,且仅创建一个,而且Application 的生命周期等于程序的生命周期,所以我们所使用的refWatcher都是同一个
    private RefWatcher refWatcher;

    @Override
    public void onCreate() {
        super.onCreate();
        if (LeakCanary.isInAnalyzerProcess(this)) {
            // This process is dedicated to LeakCanary for heap analysis.
            // You should not init your app in this process.
            return;
        }
        refWatcher = LeakCanary.install(this);
    }
}

随后在我们的Fragment中,当Fragment销毁的时候,refWatcher.watch(fragment)

public class MonitoringFragment extends Fragment {
    RefWatcher refWatcher;

    @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_monitoring, container, false);
        //这里在CommentUtils里重载了一个getUtils方法,目的是让utils 持有fragment,造成内存泄漏
        CommentUtils utils = CommentUtils.getUtils(this);
        return view;
    }

    @Override public void onDestroy() {
        super.onDestroy();
        refWatcher = MyApplication.getRefWatcher(getActivity());
        refWatcher.watch(this);
    }
}

其他的逻辑例如在Activity中添加Fragment,在这里就不贴代码了,感兴趣的可以下载demo看下

猜你喜欢

转载自blog.csdn.net/MingJieZuo/article/details/80652380