Android架构组件 – App Startup入门

施阎宝
2023-12-01

翻译自android官网

App Startup库提供了一种直接,高效的方法,可以在应用程序启动时初始化组件。库开发人员和应用程序开发人员都可以使用 app startup 来简化启动顺序并显式设置初始化顺序。

App Startup无需为需要初始化的每个组件定义单独的content provider,而是允许您定义共享单个content provider的组件初始化程序。这可以大大缩短应用程序的启动时间。

Setup 设定

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

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

Initialize components at app startup 在应用启动时初始化组件

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

若要使用App Startup在启动时自动初始化组件,必须为应用程序需要初始化的每个组件定义一个component initializer

Implement component initializers 实现组件初始化器

可以通过创建实现该Initializer< T >接口的类来定义每个 component initializer 程序。该接口定义了两个重要的方法:

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

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

// 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启动。定义一个ExampleLoggerInitializer实现 类Initializer< ExampleLogger >:

// 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);
    }
}

由于您包含WorkManagerInitializer在dependencies()方法中,因此App Startup会在ExampleLogger之前进行初始化WorkManager。

注意:如果您以前使用content provider来初始化应用程序中的组件,请确保在使用 App Startup 时删除这些content provider

Set up manifest entries 设置清单条目

App Startup包含一个特殊的内容提供程序InitializationProvider ,该提供程序用于发现和调用组件初始化程序App Startup通过首先检查清单条目< meta-data >下的InitializationProvider条目来发现组件初始化程序。然后,App Startup dependencies()为其已发现的所有初始化程序调用 方法。

这意味着为了使组件启动程序可被App Startup发现,必须满足以下条件之一:

  • 组件初始化程序 < meta-data >在InitializationProvider清单条目下具有一个对应的 条目
  • 组件初始化程序在dependencies()方法中从已经可以发现的初始化程序中列出

再次考虑使用WorkManagerInitializer和 ExampleLoggerInitialize的示例。为确保App Startup可以发现这些初始化程序,请将以下内容添加到清单文件中:

<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 >条目,因为WorkManagerInitializer是ExampleLoggerInitializer的依赖项。这意味着如果ExampleLoggerInitializer可以发现,则WorkManagerInitializer也是如此

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

Run lint checks

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:

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

结果,由于WorkManager是ExampleLogger的依赖项,因此App Startup也将初始化WorkManager。

 类似资料: