App Startup:初始化依赖图 · AndroidX 源码指南
AAndroidX 源码指南
后台与启动
后台与启动 · 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。
  • 循环依赖、重活阻塞是两大坑。

相关页面