AndroidStudio中接入LeakCanary

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011386173/article/details/82983237

LeakCanary是一个很好的检测内存泄漏的开源项目。

 

github地址:https://github.com/square/leakcanary

LeakCanary使用教程:

1、配置build.gradle

dependencies {
  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'
}

2、自定义Application类,并在其中调用LeakCanary的install函数进行安装

public class ExampleApplication 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...
  }
}

3、在AndroidManifest.xml中为Application name指定为自定义的Application

<application
        android:name=".TestApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:persistent="true">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
</application>

4、运行应用

关于leaks图标的出现时间

Leaks图标并不会跟随应用安装的同时安装,而是如果应用发生内存泄漏时,状态栏才会出现图标,状态栏出现该图标时是在dump 内存泄漏的堆栈,dump结束后桌面才会出现应用图标。

也就是说,如果应用不存在内存泄漏,状态栏不会出现,桌面也就不会出现

5、实例

(1)配置build.gradle

该应用(testDynamicReceiver)中的build.gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.4'
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        mavenCentral()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

Module:app下的build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.atc6111.testdymamicreceiver"
        minSdkVersion 27
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    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'
}

(2)自定义Application

package com.example.testdymamicreceiver;

import android.app.Application;
import android.util.Log;

import com.squareup.leakcanary.LeakCanary;

public class TestApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        if (LeakCanary.isInAnalyzerProcess(this)) {
            return;
        }
        LeakCanary.install(this);
    }
}

(3)修改AndroidManifest.xml

    <application
        android:name=".TestApplication"  
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:persistent="true">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

(4)MainActivity.java

参考github上的sample编写的:

public class MainActivity extends AppCompatActivity {

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

    void startAsyncTask() {
        // 这个AsyncTask是一个匿名内部类,因此他隐式的持有一个外部类
        // 的对象,也就是MainActivity。如果MainActivity在AsyncTask
        // 执行完成前就销毁了,这个activity实例就发生了泄露。
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                SystemClock.sleep(20000); // 休眠20秒
                return null;
            }
        }.execute();
    }
}

(5)多次进入退出(back键)应用的MainActivity

    ①出现内存泄漏时,状态栏出现图标,点击图标:

②heap dump结束后

  ③然后,桌面就会出现leaks图标

④点击进入leaks

⑤点击ReportFragment leaked

同时可借鉴的其他文章链接:

Android 内存泄漏分析利器——leakcanary

Android 排查内存神器-LeakCanary

Android内存优化(六)LeakCanary使用详解

猜你喜欢

转载自blog.csdn.net/u011386173/article/details/82983237