后台与启动
后台与启动 · androidx.work
App Startup:初始化依赖图Work 2.12.0-beta01
用 Initializer 合并 ContentProvider,并控制 eager 与 lazy 初始化。
最后更新 2026-08-01
复制即用:定义 Initializer
class NetworkInitializer : Initializer<NetworkClient> {
override fun create(context: Context): NetworkClient =
NetworkClient.create(context.applicationContext)
override fun dependencies(): List<Class<out Initializer<*>>> =
emptyList()
}
class AnalyticsInitializer : Initializer<Analytics> {
override fun create(context: Context): Analytics {
val network = AppInitializer.getInstance(context)
.initializeComponent(NetworkInitializer::class.java)
return Analytics.create(network)
}
override fun dependencies(): List<Class<out Initializer<*>>> =
listOf(NetworkInitializer::class.java)
}Manifest 注册(eager)
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false">
<meta-data
android:name="com.example.app.AnalyticsInitializer"
android:value="androidx.startup" />
</provider>dependencies() 建立有向依赖图:AppInitializer 先初始化依赖再创建当前组件,并检测循环。默认 InitializationProvider 从 manifest metadata 发现 eager initializer。
Lazy 初始化
不需要 eager 的组件从 manifest 移除自动发现,需要时手动初始化:
// manifest 中移除该 initializer 的 meta-data
// 真正需要时
val analytics = AppInitializer.getInstance(context)
.initializeComponent(AnalyticsInitializer::class.java)缓存原则:同一组件由 AppInitializer 缓存,initializeComponent 返回同一实例——不要再手工创建第二套。
启动路径的边界
只放必须尽早完成且足够轻的工作:
| ✅ 适合 eager | ❌ 不适合 |
|---|---|
| SDK 注册、轻量日志 | 数据库预热 |
| 缓存目录创建 | 网络请求 |
| 简单单例 | 大规模扫描 |
不要因为”统一初始化”就把重活全塞进 create——它会拖慢启动。
常见陷阱
- 循环依赖:Initializer A 依赖 B、B 依赖 A → 运行时异常。
- create 里做重活:阻塞 Application.onCreate。
- 手工创建第二套实例:绕过 AppInitializer 缓存。
- 忘 manifest meta-data:注册了但没 meta-data,不触发。
- 依赖获取方式错:用
AppInitializer.getInstance(context).initializeComponent(...)而非自己 new。
复制即用
// Initializer
class CrashReporterInitializer : Initializer<CrashReporter> {
override fun create(context: Context): CrashReporter =
CrashReporter.init(context.applicationContext)
override fun dependencies() = emptyList<Class<out Initializer<*>>>()
}
// manifest
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false">
<meta-data
android:name="com.example.app.CrashReporterInitializer"
android:value="androidx.startup" />
</provider>要点
Initializer+dependencies()构成依赖图;manifest meta-data 触发 eager。- 重活别进 create;lazy 用
initializeComponent手动触发。 - AppInitializer 缓存实例,别手工 new。
- 循环依赖、重活阻塞是两大坑。