LeakCanary has recently been upgraded to version 2.0 with a number of performance improvements, but one of the things that fascinates me is that it does not require manual initialization as before.
According to the previous application process, we usually add dependencies in dependencies
Dependencies {debugImplementation 'com. Squareup. Leakcanary: leakcanary - android: 1.6.3' releaseImplementation 'com. Squareup. Leakcanary: leakcanary - android - no - op: 1.6.3' / / Optional, if you use the support library fragments could: DebugImplementation 'com. Squareup. Leakcanary: leakcanary - support - fragments: 1.6.3'}Copy the code
Then add the initialization logic to our application.
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... }}Copy the code
However, the new version of LeakCanary 2.0 does not need to write this operation, but simply adds the dependency to the code
Dependencies {debugImplementation 'com. Squareup. Leakcanary: leakcanary - android: 2.0 - alpha - 1'}Copy the code
I was a little suspicious of my eyes and looked at their Readme again to see if it was true
Getting started Add LeakCanary to your
build.gradle:
Dependencies {debugImplementation com. Squareup. Leakcanary: leakcanary - android: 2.0 - alpha - 1 '}
You’re good to go! LeakCanary will automatically show a notification when an activity or fragment memory leak is detected in your debug build.
Well, that’s true. So how does it work? It’s amazing that there is a place that needs to be initialized. Where did it go?
After the interpretation of the source code, found a SAO operation, feel spread, after the SDK library may do so, teach bad children.
ContentProvider
After reading the source code, I found that actually CP is based on this for the vast majority of development, the basic use of one of the four components to do, it is really taken ha ha. Check the androidmanifest.xml file of his Leakcancanary – Leaksentry module and you can see the following:
<? 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>
Copy the code
Let’s take a look at what the LeakSentryInstaller class does.
internal class LeakSentryInstaller : ContentProvider() { override fun onCreate(): Boolean { CanaryLog.logger = DefaultCanaryLog() val application = context!! . ApplicationContext as Application InternalLeakSentry. Install (Application) / / SAO operations here, use the system automatically calls the CP onCreate method to do initializationreturn 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? {
returnnull } override fun insert( uri: Uri, contentValues: ContentValues? ) : Uri? {returnnull } override fun delete( uri: Uri, s: String? , strings: Array<String>? ) : Int {return0 } override fun update( uri: Uri, contentValues: ContentValues? , s: String? , strings: Array<String>? ) : Int {return0}}Copy the code
We see that the CP class does not do any CURD operations, all empty, pure use of the system will call the interface to do initialization, help the development lazy, save the call write initialization logic.
Personally, I see this as a two-pronged benefit: it does bring “no intrusion” and does not require business people to write any code. The usual startup sequence is Application->attachBaseContext =====>ContentProvider->onCreate =====>Application->onCreate =====>Activity->onCreate so for most scenarios, writing in CP initialization is actually enough priority!!
Cons: This is a bit of CP to use crooked. It’s going to be really cute if everyone does this and the SDKS are written this way.
ref
- Github.com/square/leak…