前言
Android Startup提供一种在应用启动时能够更加简单、高效的方式来初始化组件。开发人员可以使用Android Startup
来简化启动序列,并显式地设置初始化顺序与组件之间的依赖关系。 与此同时,Android Startup
支持同步与异步等待、手动控制依赖执行时机,并通过有向无环图拓扑排序的方式来保证内部依赖组件的初始化顺序。
Android Startup
经过几轮的迭代已经更加完善了,支持的功能场景也更加多样,如果你要使用Android Startup
的新特性,请将依赖升级到最新版本latest release
dependencies {
implementation 'com.rousetime.android:android-startup:latest release'
}
在之前的我为何弃用Jetpack的App Startup?文章中有提供一张与App Startup的对比图,现在也有了一点变化
指标 | App Startup | Android Startup |
---|---|---|
手动配置 | ✅ | ✅ |
自动配置 | ✅ | ✅ |
依赖支持 | ✅ | ✅ |
闭环处理 | ✅ | ✅ |
线程控制 | ❌ | ✅ |
异步等待 | ❌ | ✅ |
依赖回调 | ❌ | ✅ |
手动通知 | ❌ | ✅ |
拓扑优化 | ❌ | ✅ |
核心内容都在这种对比图中,下面根据这种对比图来详细分析一下Android Startup的实现原理。
配置
手动
手动配置是通过StartupManager.Builder()来实现的,本质很简单,使用builder
模式来初始化一些必要的参数,进而来获取StartupManager
实例,最后再启动Android Startup
。
val config = StartupConfig.Builder()
.setLoggerLevel(LoggerLevel.DEBUG)
.setAwaitTimeout(12000L)
.setListener(object : StartupListener {
override fun onCompleted(totalMainThreadCostTime: Long, costTimesModels: List<CostTimesModel>) {
// can to do cost time statistics.
costTimesLiveData.value = costTimesModels
Log.d("StartupTrack", "onCompleted: ${costTimesModels.size}")
}
})
.build()
StartupManager.Builder()
.setConfig(config)
.addStartup(SampleFirstStartup())
.addStartup(SampleSecondStartup())
.addStartup(SampleThirdStartup())
.addStartup(SampleFourthStartup())
.build(this)
.start()
.await()
自动
另一种方式是自动配置,开发者不需要手动调用StartupManager.Builder()
,只需在AndroidManifest.xml
文件中进行配置。
<provider
android:name="com.rousetime.android_startup.provider.StartupProvider"
android:authorities="${applicationId}.android_startup"
android:exported="false">
<meta-data
android:name="com.rousetime.sample.startup.SampleStartupProviderConfig"
android:value="android.startup.provider.config" />
<meta-data
android:name="com.rousetime.sample.startup.SampleFourthStartup"
android:value="android.startup" />
</provider>
而实现这种配置的原理是:Android Startup
内部是通过一个ContentProvider
来实现自动配置的,在Android
中ContentProvider
的初始化时机介于Application
的attachBaseContext
与onCreate
之间。所以Android Startup
借助这一特性将初始化的逻辑都封装到自定义的