1. 程式人生 > >Android之LeakCanary使用教程

Android之LeakCanary使用教程

安卓開發,新增使用最常用的記憶體洩漏檢測LeakCanary。記憶體洩漏同樣也是安卓面試和開發中最常見的問題之一。

一直在使用這個檢測記憶體洩漏,在此總結一下。

記憶體洩漏的原因:

1.在module的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'

2.AndroidManifest.xml中新增許可權 :(文末:Android6.0的許可權動態申請

<!--SDCard中建立與刪除檔案許可權-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!--向SDCard寫入資料許可權-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

3.1.Android專案中,找到Application類(若沒有,則新建並在AndroidManifest中宣告),

在Application類onCreate()方法中新增如下程式碼:

if (LeakCanary.isInAnalyzerProcess(this)) {
    return;
}
LeakCanary.install(this);

但是,只能在Activity中進行記憶體洩漏檢測。 

3.2.上述預設會檢測Activity,但是不會去檢測Fragment,若需要對某個Fragment檢測,則需要以下程式碼:

//在自己的Application中新增如下程式碼
public static RefWatcher getRefWatcher(Context context) {
	App application = (App) context.getApplicationContext();
	return application.refWatcher;
}
 
private RefWatcher refWatcher;
@Override
public void onCreate() {
	super.onCreate();

	refWatcher = LeakCanary.install(this);
}
//在Activity中新增如下程式碼
@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	//初始時加入如下兩行程式碼
	RefWatcher refWatcher = MyApp.getRefWatcher(this);
	refWatcher.watch(this);
    //... ...
}

4.檢測某個特定的物件,如下程式碼:

假設物件為mObject

RefWatcher refWatcher = MyApp.getRefWatcher(this);
refWatcher.watch(mObject);

mObject這個物件還在記憶體中被其他物件引用,就會在 logcat 裡看到記憶體洩漏的提示。

5.Android6.0中的配置

因為Android6.0的許可權需要動態申請,不僅要在AndroidManifest.xml中新增許可權,而且需要程式碼中動態申請:

動態申請的程式碼:

private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
            "android.permission.READ_EXTERNAL_STORAGE",
            "android.permission.WRITE_EXTERNAL_STORAGE" };

public static void verifyStoragePermissions(Activity activity) {
    try {
        //檢測是否有寫的許可權
        int permission = ActivityCompat.checkSelfPermission(activity,
                    "android.permission.WRITE_EXTERNAL_STORAGE");
        if (permission != PackageManager.PERMISSION_GRANTED) {
            // 沒有寫的許可權,去申請寫的許可權,會彈出對話方塊
            ActivityCompat.requestPermissions(activity,
                           PERMISSIONS_STORAGE,REQUEST_EXTERNAL_STORAGE);
        }
    } catch (Exception e) {
            e.printStackTrace();
    }
}

在第一個Activity中呼叫:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //申請許可權
        verifyStoragePermissions(this);
}

6.LeakCanary實現原理: