A daily Q: Tell me what you know about the LeakCanary

Speaking about yesterday's problems point to note is a memory leak in the last, there comes LeakCanary detect memory leaks. In fact, I believe most people know even used this library.

In general, this series if we find a good resource, will choose to directly take over part of the interception, so the reference link at the bottom of the article are generally very good, you can go directly to yo ~

The basic workflow LeakCanary is like?

LeakCanary of use is very simple, just write directly dependent on the build.gradle inside, and do register in the Application class inside it.

Of course, the need to register in the Application which such operations only in version 1.x, most people contact, in fact LeakCanary now been upgraded to version 2.x, the code less invasive, and pure Kotlin writing. The main push Google from a variety of Demo Kotlin and all major libraries are written using Kotlin Kotlin really seen the point of view increasingly important in the development of Android, you did not have to use a small partner to learn a wave, and now I am also doing development pure Kotlin of.

For works more or less I believe we should also have a certain understanding, where there are just a very good flow diagram directly borrowed, the other his understanding LeakCanary this article from the perspective of the source code is also written in a very good interest click the link at the bottom of the article directly.

6544890-9a37807f59f71b55.png

Why is there no first use LeakCanary entrance Icon

We often when using LeakCanary will find such a problem: the beginning Launcher icon LeakCanary did not occur, but a memory leak when the warning system on the desktop such a icons and more, under normal circumstances are very curious .

1.x from the source can be discerned. In manifast leakcanary-android, we can see the relevant configuration:

<!--leakcanary-sample/src/main/AndroidManifest.xml-->
<service
    android:name=".internal.HeapAnalyzerService"
    android:process=":leakcanary"
    android:enabled="false"
    />
<service
    android:name=".DisplayLeakService"
    android:process=":leakcanary"
    android:enabled="false"
    />
<activity
    android:theme="@style/leak_canary_LeakCanary.Base"
    android:name=".internal.DisplayLeakActivity"
    android:process=":leakcanary"
    android:enabled="false"
    android:label="@string/leak_canary_display_activity_label"
    android:icon="@mipmap/leak_canary_icon"
    android:taskAffinity="com.squareup.leakcanary.${applicationId}"
    >
  <intent-filter>
    <action android:name="android.intent.action.MAIN"/>
    <category android:name="android.intent.category.LAUNCHER"/>
  </intent-filter>
</activity>

We can see that DisplayLeakActivityhas been set to Launcher, and set on the corresponding icon, so we use LeakCanary generate Icon entry in the desktop. However, DisplayLeakActivitythe enableproperty defaults to false, so are not displayed on the desktop portal. And in the event of a memory leak, LeakCanary will take the initiative to enableproperty set to true.

LeakCanary 2 have done

LeakCanary recently upgraded to version 2.x, this is a complete reconstruction, to air bag leakcanary-android-no-op cited under 1.x release in addition to the environment. And Kotlin language coverage of up to 99.8%, also no longer need to do something like the following code in the Application inside.

//com.example.leakcanary.ExampleApplication
@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);
}

Just add this code which relies on it.

dependencies {
  debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0-alpha-2'
}

For the first time to see such an operation, you will feel very magical, just read the source code back to find that it actually uses a Sao operation: ContentProvider.

In leakcanary-leaksentrythe module AndroidManifest.xmlfile can be seen:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.squareup.leakcanary.leaksentry"
    >

  <application>
    <provider
        android:name="leakcanary.internal.LeakSentryInstaller"
        android:authorities="${applicationId}.leak-sentry-installer"
        android:exported="false"/>
  </application>
</manifest>

Then after viewing LeakSentryInstallercan be seen:

package leakcanary.internal

import android.app.Application
import android.content.ContentProvider
import android.content.ContentValues
import android.database.Cursor
import android.net.Uri
import leakcanary.CanaryLog

/**
 * Content providers are loaded before the application class is created. [LeakSentryInstaller] is
 * used to install [leaksentry.LeakSentry] on application start.
 */
internal class LeakSentryInstaller : ContentProvider() {

  override fun onCreate(): Boolean {
    CanaryLog.logger = DefaultCanaryLog()
    val application = context!!.applicationContext as Application
    InternalLeakSentry.install(application)
    return true
  }

  override fun query(
    uri: Uri,
    strings: Array<String>?,
    s: String?,
    strings1: Array<String>?,
    s1: String?
  ): Cursor? {
    return null
  }

  override fun getType(uri: Uri): String? {
    return null
  }

  override fun insert(
    uri: Uri,
    contentValues: ContentValues?
  ): Uri? {
    return null
  }

  override fun delete(
    uri: Uri,
    s: String?,
    strings: Array<String>?
  ): Int {
    return 0
  }

  override fun update(
    uri: Uri,
    contentValues: ContentValues?,
    s: String?,
    strings: Array<String>?
  ): Int {
    return 0
  }
}

Sao indeed true, but savoring the feel is really very clever.

Reference: https://www.jianshu.com/p/49239eac7a76

Reproduced in: https: //www.jianshu.com/p/817b52d05a12

Guess you like

Origin blog.csdn.net/weixin_34146410/article/details/91117588