• build gradle配置

    1
    2
    3
    4
    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

    1
    2
    3
    4
    5
    6
    7
    8
    private RefWatcher refWatcher;

    public static RefWatcher getRefWatcher(Context context){

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

    return application.refWatcher;
    }
  • 监测

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@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 给我们的提示:

image.png

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

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

这样就不会有警告了。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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);
}
}

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

-------------本文结束感谢您的阅读-------------