安卓使用 Startup 管理三方 SDK 初始化

张开发
2026/4/9 5:02:43 15 分钟阅读

分享文章

安卓使用 Startup 管理三方 SDK 初始化
安卓使用 Startup 管理三方 SDK 初始化一、为什么要使用 Startup1. 第三方 SDK 是怎么 “悄悄初始化” 的很多 popular SDK如 Bugly、友盟、高德地图、MMKV、各类推送与统计 SDK都在自己的 AAR 包里内置了一个ContentProvider。它会在AndroidManifest.xml中注册类似这样的配置providerandroid:namecom.xxx.XXXProviderandroid:authorities${applicationId}.xxxandroid:exportedfalse/而在这个 Provider 的onCreate()里它会偷偷执行 SDK 初始化OverridepublicvoidonCreate(){XXXSDK.init(getContext());// 自动初始化}你什么都不用做App 一启动几十个 SDK 就在主线程排队初始化直接拖慢冷启动速度。2. 为什么 ContentProvider 会自动执行系统启动 App 的流程是固定的Zygote 孵化出 App 进程创建 Application执行attachBaseContext()实例化并执行所有 Manifest 中注册的 ContentProvider执行Application.onCreate()启动第一个 Activity关键点ContentProvider 的 onCreate () 会在 Application.onCreate () 之前自动执行所以 SDK 利用这个 “系统钩子” 实现自动初始化结果就是App 还没进入你的代码已经被一堆 SDK 卡死在启动阶段。3. Jetpack Startup 解决了什么问题App Startup 的核心使命非常简单用一个统一的 ContentProvider替代所有 SDK 各自为政的 N 个 ContentProvider。只保留一个providerandroid:nameandroidx.startup.InitializationProviderandroid:authorities${applicationId}.androidx-startupandroid:exportedfalse/好处减少大量组件创建开销统一管理 SDK 初始化顺序支持依赖声明 → 自动拓扑排序支持手动 / 懒加载控制它不是禁用 ContentProvider而是把被滥用的 “自动初始化钩子” 重新收归统一管理。4.Startup 的核心作用总结取消每个 SDK 自己私有的 Provider把所有初始化逻辑集中到你写的 Initializer通过 dependencies () 声明依赖 → 自动按顺序执行不会乱并发、不会乱序、不会阻塞主线程二、使用startup1. 引入依赖implementationandroidx.startup:startup-runtime:1.2.02. 新建多个Initializer类MainInitializer.kt备注统一入口可选packagecom.example.startupdemo.initializerimportandroid.content.Contextimportandroidx.startup.AppInitializerimportandroidx.startup.InitializerclassMainInitializer:InitializerUnit{overridefuncreate(context:Context){// 这里写所有需要启动初始化的库 println(初始化MainInitializer)initNetwork(context)initPush(context)// initBugly(context)// initMMKV(context)// initRouter(context)}// 网络privatefuninitNetwork(context:Context){AppInitializer.getInstance(context).initializeComponent(NetworkInitializer::class.java)}// 推送privatefuninitPush(context:Context){AppInitializer.getInstance(context).initializeComponent(PushInitializer::class.java)}// 依赖如果没有依赖其他Initializer就空overridefundependencies():ListClassoutInitializer*emptyList()}CrashInitializer.ktpackagecom.example.startupdemo.initializerimportandroid.content.Contextimportandroidx.startup.InitializerclassCrashInitializer:InitializerUnit{overridefuncreate(context:Context){// 执行崩溃库初始化println(初始化崩溃监控)}/** * 表示当前的 Initializer 是否还依赖于其他的 Initializer如果有的话就在这里进行配置 * App Startup 会保证先初始化依赖的 Initializer然后才会初始化当前的 Initializer */overridefundependencies():ListClassoutInitializer*emptyList()}NetworkInitializer.ktpackagecom.example.startupdemo.initializerimportandroid.content.Contextimportandroidx.startup.InitializerclassNetworkInitializer:InitializerUnit{overridefuncreate(context:Context){// 执行网络库初始化println(初始化网络框架)}/** * 表示当前的 Initializer 是否还依赖于其他的 Initializer如果有的话就在这里进行配置 * App Startup 会保证先初始化依赖的 Initializer然后才会初始化当前的 Initializer */overridefundependencies():ListClassoutInitializer*listOf(CrashInitializer::class.java)}PushInitializer.ktpackagecom.example.startupdemo.initializerimportandroid.content.Contextimportandroidx.startup.InitializerclassPushInitializer:InitializerUnit{overridefuncreate(context:Context){// 执行推送初始化println(初始化推送服务)}/** * 表示当前的 Initializer 是否还依赖于其他的 Initializer如果有的话就在这里进行配置 * App Startup 会保证先初始化依赖的 Initializer然后才会初始化当前的 Initializer */overridefundependencies():ListClassoutInitializer*listOf(NetworkInitializer::class.java)}3. 初始化方式 A代码手动初始化推荐更灵活、不抢启动、最安全// 在 Application 或 MainActivity 中AppInitializer.getInstance(this).initializeComponent(MainInitializer::class.java)方式 BXML 自动初始化不推荐providerandroid:nameandroidx.startup.InitializationProviderandroid:authorities${applicationId}.androidx-startupandroid:exportedfalsetools:nodemergemeta-dataandroid:namecom.example.startupdemo.initializer.MainInitializerandroid:valueandroidx.startup//provider警告如果不用 XML 配置可以删除meta-data或使用tools:noderemove让它失效。4. 运行结果与demo下载demo初始化MainInitializer 初始化崩溃监控 初始化网络框架 初始化推送服务为什么顺序是这样NetworkInitializer 依赖 CrashInitializerPushInitializer 依赖 NetworkInitializerStartup 自动执行拓扑排序→ 先依赖后当前由此实现初始化顺序完全可控自动初始化 vs 懒加载 二选一启动速度显著提升减少 ContentProvider 数量代码结构更清晰、更好维护

更多文章