应用启动 Android Jetpack 的一部分。

App Startup 库提供了一种简单、高效的方法来初始化 启动组件。库开发者和应用开发者 可以使用应用启动来简化启动顺序并明确设置启动顺序 进行初始化。

您无需为每个组件定义单独的 content provider,您需要 initialize 时,通过应用启动,您可以定义共用 一个 content provider。这可以显著缩短应用启动时间。

设置

如需在库或应用中使用 Jetpack Startup,请将以下代码添加到 Gradle 中 文件:

Groovy

dependencies {
    implementation "androidx.startup:startup-runtime:1.2.0"
}

Kotlin

dependencies {
    implementation("androidx.startup:startup-runtime:1.2.0")
}

在应用启动时初始化组件

应用和库通常依赖于在运行代码时立即初始化组件 应用启动。为了满足这一需求,你可以使用内容提供方 初始化每个依赖项,但 content provider 的实例化成本很高 并且可能会不必要地减慢启动序列的速度此外,Android 以不确定的顺序初始化 content provider。应用启动提供了一种 用于在应用启动时初始化组件的 定义其依赖项

若要使用应用启动功能在启动时自动初始化组件,您必须: 为应用需要为每个组件定义一个组件初始化程序 初始化。

实现组件初始化程序

您可以创建一个类,以实现 Initializer<T> 接口。 此接口定义了两个重要方法:

  • create() 方法,其中包含调用 API 时所需的所有操作 初始化组件并返回 T 的实例。
  • dependencies() 方法,该方法会返回另一个 初始化程序依赖的 Initializer<T> 对象。您可以使用 方法来控制应用在启动时运行初始化程序的顺序。

例如,假设您的应用依赖于 WorkManager,并且需要 并在启动时对其进行初始化。定义一个 WorkManagerInitializer 类,用于 实现 Initializer<WorkManager>

Kotlin

// Initializes WorkManager.
class WorkManagerInitializer : Initializer<WorkManager> {
    override fun create(context: Context): WorkManager {
        val configuration = Configuration.Builder().build()
        WorkManager.initialize(context, configuration)
        return WorkManager.getInstance(context)
    }
    override fun dependencies(): List<Class<out Initializer<*>>> {
        // No dependencies on other libraries.
        return emptyList()
    }
}

Java

// Initializes WorkManager.
class WorkManagerInitializer implements Initializer<WorkManager> {

    @Override
    public WorkManager create(Context context) {
        Configuration configuration = Configuration.Builder().build();
        WorkManager.initialize(context, configuration);
        return WorkManager.getInstance(context);
    }

    @Override
    public List<Class<Initializer<?>>> dependencies() {
        // No dependencies on other libraries.
        return emptyList();
    }

}

dependencies() 方法会返回空列表,因为 WorkManager 不会 依赖于任何其他库

假设您的应用还依赖于一个名为 ExampleLogger 的库,该库在 依赖于WorkManager。这种依赖项意味着 App Startup 首先初始化 WorkManager。定义 实现 Initializer<ExampleLogger>ExampleLoggerInitializer 类:

Kotlin

// Initializes ExampleLogger.
class ExampleLoggerInitializer : Initializer<ExampleLogger> {
    override fun create(context: Context): ExampleLogger {
        // WorkManager.getInstance() is non-null only after
        // WorkManager is initialized.
        return ExampleLogger(WorkManager.getInstance(context))
    }

    override fun dependencies(): List<Class<out Initializer<*>>> {
        // Defines a dependency on WorkManagerInitializer so it can be
        // initialized after WorkManager is initialized.
        return listOf(WorkManagerInitializer::class.java)
    }
}

Java

// Initializes ExampleLogger.
class ExampleLoggerInitializer implements Initializer<ExampleLogger> {

    @Override
    public ExampleLogger create(Context context) {
        // WorkManager.getInstance() is non-null only after
        // WorkManager is initialized.
        return ExampleLogger(WorkManager.getInstance(context));
    }

    @Override
    public List<Class<Initializer<?>>> dependencies() {
        // Defines a dependency on WorkManagerInitializer so it can be
        // initialized after WorkManager is initialized.
        return Arrays.asList(WorkManagerInitializer.class);
    }
}

由于您在 dependencies() 方法中添加了 WorkManagerInitializer,因此应用 Startup 会在 ExampleLogger 之前初始化 WorkManager

设置清单条目

App Startup 包含一个名为 InitializationProvider 的特殊 content provider 来发现和调用组件初始化程序。应用启动 通过首先检查是否存在 <meta-data> 条目来发现组件初始化程序 (位于 InitializationProvider 清单条目下)。然后,应用启动会调用 dependencies() 方法。

这意味着,为了让应用能够发现组件初始化程序, 启动,必须满足以下条件之一:

  • 组件初始化程序在<meta-data> InitializationProvider 清单条目。
  • 组件初始化程序列在dependencies() 已发现的初始化程序。

我们再来看一下包含 WorkManagerInitializerExampleLoggerInitializer。为了确保应用启动功能可以发现这些 初始化程序,请将以下内容添加到清单文件中:

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">
    <!-- This entry makes ExampleLoggerInitializer discoverable. -->
    <meta-data  android:name="com.example.ExampleLoggerInitializer"
          android:value="androidx.startup" />
</provider>

您无需为 WorkManagerInitializer 添加 <meta-data> 条目, 因为 WorkManagerInitializerExampleLoggerInitializer 的依赖项。 这意味着,如果 ExampleLoggerInitializer 可检测到,那么也 WorkManagerInitializer

tools:node="merge" 属性可确保清单合并程序 工具可以正确解决所有冲突的条目。

运行 lint 检查

App Startup 库包含一组 lint 规则,可用于检查 您是否已正确定义组件初始化程序您可以执行 执行这些 lint 检查。./gradlew :app:lintDebug

手动初始化组件

通常,当您使用应用启动时,InitializationProvider 对象会使用 名为 AppInitializer更改为 在应用启动时自动发现并运行组件初始化程序。 不过,您也可以直接使用 AppInitializer,以便手动 初始化您的应用在启动时不需要的组件。这称为 延迟初始化,有助于将启动成本降至最低。

您必须先对所需的任何组件停用自动初始化 手动初始化

为单个组件停用自动初始化功能

要停用单个组件的自动初始化,请移除 清单中该组件的初始化程序的 <meta-data> 条目。

例如,将以下内容添加到清单文件中会停用自动 ExampleLogger 的初始化:

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">
    <meta-data android:name="com.example.ExampleLoggerInitializer"
              tools:node="remove" />
</provider>

您可以在条目中使用 tools:node="remove",而不是直接移除该条目 以确保合并工具还会将相应条目从其他所有列表中删除 合并的清单文件

为所有组件停用自动初始化功能

要停用所有自动初始化,请删除 InitializationProvider

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove" />

手动调用组件初始化程序

如果对某个组件停用了自动初始化功能,您可以使用 AppInitializer,用于手动初始化该组件及其依赖项。

例如,以下代码调用 AppInitializer 并手动初始化 ExampleLogger

Kotlin

AppInitializer.getInstance(context)
    .initializeComponent(ExampleLoggerInitializer::class.java)

Java

AppInitializer.getInstance(context)
    .initializeComponent(ExampleLoggerInitializer.class);

因此,应用启动也会初始化 WorkManager,因为 WorkManagerExampleLogger 的依赖项。

提供反馈

通过以下资源与我们分享您的反馈和想法:

问题跟踪器
报告问题,以便我们可以修复错误。