漫畫安卓:使用LeakCanary快速簡單排查Android中的內存泄露

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
1)在項目的build.gradle文件添加:

debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
    testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
複製代碼

能夠看到,debugCompile跟releaseCompile 引入的是不一樣的包, 在 debug 版本上,集成 LeakCanary 庫,並執行內存泄漏監測,而在 release 版本上,集成一個無操做的 wrapper ,這樣對程序性能就不會有影響。android

2)在Application類添加:bash

public class LCApplication 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);
        // Normal app init code...
    }
}
複製代碼

LeakCanary.install() 會返回一個預約義的 RefWatcher,同時也會啓用一個 ActivityRefWatcher,用於自動監控調用 Activity.onDestroy() 以後泄露的 activity。app

若是是簡單的檢測activity是否存在內存泄漏,上面兩個步驟就能夠了,是否是很簡單。 那麼當某個activity存在內存泄漏的時候,會有什麼提示呢?LeakCanary會自動展現一個通知欄,點開提示框你會看到引發內存溢出的引用堆棧信息。ide

這裏寫圖片描述
在這裏插入圖片描述
具體使用代碼

1)Application 相關代碼:性能

public class LCApplication 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);
        // Normal app init code...
    }

}
複製代碼

2)泄漏的activity類代碼:學習

public class MainActivity extends Activity {

    private Button next;

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

        next = (Button) findViewById(R.id.next);
        next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
                finish();
            }
        });
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("=================");
                }
            }
        }).start();
    }
}
複製代碼

當點擊next跳到第二個界面後,LeakCanary會自動展現一個通知欄,點開提示框你會看到引發內存溢出的引用堆棧信息,如上圖所示,這樣你就很容易定位到原來是線程引用住當前activity,致使activity沒法釋放。 gradle

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
上面提到,LeakCanary.install() 會返回一個預約義的 RefWatcher,同時也會啓用一個 ActivityRefWatcher,用於自動監控調用 Activity.onDestroy() 以後泄露的 activity。如今不少app都使用到了fragment,那fragment如何檢測呢。

1)Application 中獲取到refWatcher對象。ui

public class LCApplication extends Application {

    public static 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);
        // Normal app init code...
    }
}
複製代碼

2)使用 RefWatcher 監控 Fragment:this

public abstract class BaseFragment extends Fragment {
  @Override public void onDestroy() {
    super.onDestroy();
    RefWatcher refWatcher = LCApplication.refWatcher;
    refWatcher.watch(this);
  }
}
複製代碼

這樣則像監聽activity同樣監聽fragment。其實這種方式同樣適用於任何對象,好比圖片,自定義類等等,很是方便。 下一篇將介紹LeakCanary的檢測原理,先學會使用,再瞭解原理。spa

5.源碼下載地址

demo下載地址


若有錯誤歡迎指出來,一塊兒學習。

在這裏插入圖片描述
相關文章
相關標籤/搜索