Android Jetpack 之 App Startup

tech2026-03-17  1

       我们平常在项目开发中,会引入或多或少第三方sdk,引入时基本上都需要初始化,而大部分sdk初始化,都提倡在 Application的onCreate()里面初始化,比如下面:

class MyApplication:Application() { override fun onCreate() { super.onCreate() MySdk().init(this) MySdk1().init(this) MySdk2().init(this) MySdk3().init(this) Log.d("MyTest", "MyApplication create") } }

 

这样,随着项目开发,引入的第三方sdk肯定会越来越多,这样就会让Application里面做初始化的代码非常多非常臃肿,而且太多也会影响整个App的启动效率。那有没有一种方案,既可以让 Application不那么臃肿,又提高App的启动效率呢?

Jetpack 的 AppStartup

 

怎么用呢?很简单,就三步

1.引入依赖

2.实现 Initializer 接口

3.在AndroidManifest.xml的注册

 

1.引入依赖

dependencies { implementation "androidx.startup:startup-runtime:1.0.0-alpha02" }

2.实现 Initializer 接口

class SdkInitializer : Initializer<Any> { override fun create(context: Context) { // init your sdk MySdk().init(context) Log.d("MyTest", "Initializer create") } override fun dependencies(): List<Class<out Initializer<*>>> { Log.d("MyTest", "Initializer dependencies") return emptyList() } }

3.在AndroidManifest.xml的注册

<provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <meta-data android:name="com.leo.dicaprio.myutilapp.startup.SdkInitializer" android:value="androidx.startup" /> </provider>

这里主要一下,AndroidManifest.xml注册的内容,只有 meta-data - name   可以更改,其他的地方最好不要改,也不需要改

 

就是这么简单。把需要初始化的sdk,都放在 Initializer 的 create()dependencies() 两个接口里面,具体放在哪个接口里呢?

如果你引入的sdk1,是不需要依赖其他的sdk2,那只需要把sdk1放进 create() 初始化即可,如下:

class SdkInitializer : Initializer<Any> { override fun create(context: Context) { // init your sdk MySdk1().init(context) Log.d("MyTest", "Initializer create") } override fun dependencies(): List<Class<out Initializer<*>>> { Log.d("MyTest", "Initializer dependencies") // 如果没有需要初始化的sdk,返回 空列表即可 return emptyList() } }

 

如果你引入的sdk1,是需要依赖其他的sdk2,那需要把sdk2 放进 dependencies() 里面,再把sdk1放进 create() 初始化,

因为 dependencies()  先于 create()  回调,保证sdk2 先初始化, 如下:

SdkInitializer

class SdkInitializer : Initializer<Any> { override fun create(context: Context) { // init your sdk MySdk().init(context) Log.d("MyTest", "Initializer create") } override fun dependencies(): List<Class<out Initializer<*>>> { Log.d("MyTest", "Initializer dependencies") return listOf(Sdk2Initializer::class.java) } }

 

SdkInitializer2

class Sdk2Initializer : Initializer<Any> { override fun create(context: Context) { // init your sdk MySdk2().init(context) Log.d("MyTest", "Initializer create2") } override fun dependencies(): List<Class<out Initializer<*>>> { Log.d("MyTest", "Initializer dependencies2") return emptyList() } }

 

注意,只需要注册一个Initializer , Sdk2Initializer 不需要 在AndroidManifest.xml 注册了,否则会报错...

 

启动应用,我们看下日志:

/MyTest: Initializer dependencies /MyTest: Initializer dependencies2 /MyTest: Initializer create2 /MyTest: Initializer create

看日志可得:先去初始化sdk2,再去初始化 sdk1

 

原理

上面只是说到如何使用,但是,它为啥能提高启动效率呢?先看下 Initializer 在 AndroidManifest.xml的注册,

<provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <meta-data android:name="com.leo.dicaprio.myutilapp.startup.SdkInitializer" android:value="androidx.startup" /> </provider>

其实,Initializer  就是一个 ContentProvider 。而 ContentProvider 的执行,是先于 Application的,流程如下:

 

一个应用程序的执行顺序是这个样子的。首先调用Application的attachBaseContext()方法,然后调用ContentProvider的onCreate()方法,接下来调用Application的onCreate()方法

 

我们把 sdk 的初始化 挪到 ContentProvider里面,先于Application,这样只是避免了 Application代码的臃肿,并没有看到提高啥效率了,因为该花多少时间去初始化,还得花多少时间。

 

然而,你们可记得?上面说过只需要注册一个 Initializer,不需要也不能注册多个 Initializer。其实AppStartup 之所以能提高效率正是在这里,不管你需要初始化多少个sdk,都只需要注册一个 Initializer(即:一个ContentProvider)。

很简单,注册的 ContentProvider 越多,ContentProvider启动 占用的时间就越多。但是只注册一个 ContentProvider,当然可以提高效率。

 

以上如有问题请留言指出,谢谢

 

 

 

 

 

 

 

 

 

 

 

 

 

 

最新回复(0)