小试牛刀-leakcannary

leakcanary

  • build gradle配置
    debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.1'
    releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.1'
    // Optional, if you use support library fragments:
    debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.1'
  • 配置 application
private RefWatcher refWatcher;

    public static RefWatcher getRefWatcher(Context context){

        HealthApplication application = (HealthApplication) context.getApplicationContext();

        return application.refWatcher;
    }
  • 监测
 RefWatcher refWatcher = MyApplication.getRefWatcher(this);//1
        refWatcher.watch(this);

例如:我们写一个泄漏的代码

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

        RefWatcher refWatcher = MyApplication.getRefWatcher(this);//1
        refWatcher.watch(this);


        Message message = Message.obtain();
        message.obj = "qianqian";
        message.what = 666;
        handler.sendMessageDelayed(message,600000);
    }

    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.i("xx","handle message");
        }
    };

    public void sendMessage(View view){
        finish();
    }

界面上一个按钮,点击按钮退出程序,在程序 onCreate 方法中我们发送了一个延时的消息,按照我们的分析,肯定会发生泄漏的。来我们看下leakcannary 给我们的提示:

小试牛刀-leakcannary_第1张图片
image.png

我们知道当我们退出程序的时候 MessageQueue 中的消息还没执行完毕,MessageQueue.mMessages 这个变量持有的是Message 这个对象,而 Message.target中的 target持有的该Activityhandler引用,所以此时finish 掉的 activity 并不会被回收,导致LeakActivity 发生内存泄漏。

  • 其中一种解决办法呢,就是我们可以通过在点击或activity 退出时,removeMessage,例如:
public void sendMessage(View view){
        handler.removeMessages(666);
        finish();
    }

这样就不会有警告了。

也可以通过静态内部类+弱引用的方式:

private static class MyHandler extends Handler {
    private final WeakReference mActivity;

    public MyHandler(SampleActivity activity) {
      mActivity = new WeakReference(activity);
    }

    @Override
    public void handleMessage(Message msg) {
      LeakActivityactivity = mActivity.get();
      if (activity != null) {
        ...
      }
    }
  }
private final MyHandler handler= new MyHandler(this);

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_event_bus);
        Message message = Message.obtain();
        message.obj = "qianqian";
        message.what = 666;
        handler.sendMessageDelayed(message,600000);
    }
}

在实际项目中,可以用这个工具筛查一遍。

你可能感兴趣的:(小试牛刀-leakcannary)