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
给我们的提示:
我们知道当我们退出程序的时候 MessageQueue
中的消息还没执行完毕,MessageQueue.mMessages
这个变量持有的是Message
这个对象,而 Message.target
中的 target
持有的该Activity
的 handler
引用,所以此时finish
掉的 activity
并不会被回收,导致LeakActivity
发生内存泄漏。
- 其中一种解决办法呢,就是我们可以通过在点击或
activity
退出时,removeMessage
,例如:
public void sendMessage(View view){
handler.removeMessages(666);
finish();
}
这样就不会有警告了。
也可以通过静态内部类+弱引用的方式:
private static class MyHandler extends Handler {
private final WeakReference<LeakActivity> mActivity;
public MyHandler(SampleActivity activity) {
mActivity = new WeakReference<LeakActivity>(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);
}
}
在实际项目中,可以用这个工具筛查一遍。
网友评论