应用启动   Android Jetpack 的一部分。

应用启动库提供了一种简单、高效的方式来在应用启动时初始化组件。库开发者和应用开发者都可以使用应用启动来简化启动序列并明确设置初始化顺序。

应用启动允许您定义共享单个内容提供程序的组件初始化程序,而不是为需要初始化的每个组件定义单独的内容提供程序。这可以显著提高应用启动时间。

设置

要在您的库或应用中使用 Jetpack Startup,请将以下内容添加到您的 Gradle 文件中

Groovy

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

Kotlin

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

在应用启动时初始化组件

应用和库通常依赖于在应用启动时立即初始化组件。您可以通过使用内容提供程序来初始化每个依赖项来满足此需求,但内容提供程序的实例化成本很高,并且可能会不必要地减慢启动序列。此外,Android 以不确定的顺序初始化内容提供程序。应用启动提供了一种更高效的方式来在应用启动时初始化组件并明确定义它们的依赖项。

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

实现组件初始化程序

您可以通过创建一个实现 Initializer<T> 接口的类来定义每个组件初始化程序。此接口定义了两个重要的方法

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

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

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。此依赖项意味着您需要确保应用启动首先初始化 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,所以应用启动会在 ExampleLogger 之前初始化 WorkManager

设置清单条目

应用启动包含一个名为 InitializationProvider 的特殊内容提供程序,它用于发现并调用您的组件初始化程序。应用启动首先检查 InitializationProvider 清单条目下的 <meta-data> 条目,以发现组件初始化程序。然后,应用启动会调用它已发现的任何初始化程序的 dependencies() 方法。

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

  • 组件初始化程序在 InitializationProvider 清单条目下具有相应的 <meta-data> 条目。
  • 组件初始化程序列在已可发现的初始化程序的 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>

您无需为<meta-data>添加条目以用于WorkManagerInitializer,因为WorkManagerInitializerExampleLoggerInitializer的依赖项。这意味着,如果ExampleLoggerInitializer 可发现,那么WorkManagerInitializer 也是可发现的。

tools:node="merge"属性确保清单合并工具正确解析任何冲突的条目。

运行 lint 检查

App Startup 库包含一组 lint 规则,您可以使用这些规则来检查是否已正确定义组件初始化器。您可以通过从命令行运行./gradlew :app:lintDebug来执行这些 lint 检查。

手动初始化组件

通常,当您使用 App Startup 时,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);

结果,App Startup 也初始化了WorkManager,因为WorkManagerExampleLogger的依赖项。

提供反馈

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

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