小試牛刀-leakcannary
ofollow,noindex">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
給我們的提示:

image.png
我們知道當我們退出程式的時候 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); } }
在實際專案中,可以用這個工具篩查一遍。