Android leakcanary2,LeakCanary2的免写 初始化代码 原理

这篇博客介绍了LeakCanary 2.0版本的重大改变,它不再需要手动初始化,只需在build.gradle中添加一行依赖即可。作者通过源码解析揭示了这一“骚操作”背后的原理——借助ContentProvider在应用启动时自动完成初始化。虽然带来了便利,但也可能引发滥用SDK的行为。
摘要由CSDN通过智能技术生成

最近 LeakCanary

做了升级,发布了2.0版本,带了了很多性能上的优化,不过一个很吸引我的点在于,他居然不像以前一样,需要手动初始化了。

按照以前的使用流程,一般我们都是在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 support library fragments:

debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.3'

}

复制代码

接着在我们的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...

}

}

复制代码

但是,新版本的 LeakCanary 2.0居然可以不再需要写这个操作,只需要在代码里面加入这么一句依赖就可以了

dependencies {

debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0-alpha-1'

}

复制代码

我有点怀疑自己的眼睛,重新看了下他们的 Readme

,是不是真的

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.

好吧,确实是这样,那么到底怎么做到的?很神奇啊,这怎么也会有一个地方会需要初始化的,到底换到那里去了?

在经过对源码的解读后,发现了一个骚操作,感觉传开后,以后的sdk库都可能这么做,教坏小朋友了。

ContentProvider

在经过对源码的阅读后,发现其实人家是基于CP这个对于绝大数开发来说,基本没用到的四大组件之一来做的,真的是服了哈哈。查看他的 leakcanary-leaksentry

模块的 AndroidManifest.xml

文件,可以看到下面的内容:

xmlns:android="http://schemas.android.com/apk/res/android"

package="com.squareup.leakcanary.leaksentry"

>

android:name="leakcanary.internal.LeakSentryInstaller"

android:authorities="${applicationId}.leak-sentry-installer"

android:exported="false"/>

复制代码

接着我们去看下那 LeakSentryInstaller

这个类到底做了什么。

internal class LeakSentryInstaller : ContentProvider() {

override fun onCreate(): Boolean {

CanaryLog.logger = DefaultCanaryLog()

val application = context!!.applicationContext as Application

InternalLeakSentry.install(application)

//骚操作在这里,利用系统自动调用CP的onCreate方法来做初始化

return true

}

override fun query(

uri: Uri,

strings: Array?,

s: String?,

strings1: Array?,

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?

): Int {

return 0

}

override fun update(

uri: Uri,

contentValues: ContentValues?,

s: String?,

strings: Array?

): Int {

return 0

}

}

复制代码

我们看到这个CP类,没做任何的CURD操作,全是空的,就纯粹利用系统会回调这个接口来做初始化,帮助开发偷懒,省去调用写初始化逻辑。

个人看待这个,觉得得分两部门

好处:确实带来了 "免侵入"

,不需要业务人员写任何代码。一般启动的顺序是 Application->attachBaseContext =====>ContentProvider->onCreate =====>Application->onCreate =====>Activity->onCreate

所以对于大多数场景,写在CP的初始化的实际是足够优先了!!

坏处:这有点把CP给用歪了。以后所有人都这么弄,接入的sdk都这么写的话,那就真的可爱了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值