Android Jetpack系列之应用初始化 App Startup

309 阅读3分钟

Android Jetpack系列之应用初始化 App Startup

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

App Startup允许你定义组件初始化器,而不是为你需要初始化的每个组件定义单独的内容提供者。这可以显著提高应用启动时间。

app-startup

Gradle文件中添加

  implementation("androidx.startup:startup-runtime:1.1.1")

在应用启动时初始化组件

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

要使用App Startup在启动时自动初始化组件,你必须为应用需要初始化的每个组件定义一个组件初始化器。

实现组件的初始化

通过创建一个实现initializer 接口的类来定义每个组件初始化器。这个接口定义了两个重要的方法:

1.create()方法,它包含初始化组件所需的所有操作,并返回T的一个实例。

2.dependencies()方法,它返回初始化器所依赖的其他Initializer对象的列表。您可以使用此方法来控制应用程序在启动时运行初始化器的顺序。

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

添加WorkManager依赖

 // Kotlin + coroutines
    implementation("androidx.work:work-runtime-ktx:$work_version")
// 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()
    }
}

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

假设您的应用程序还依赖于一个名为ExampleLogger的库,而ExampleLogger又依赖于WorkManager。这个依赖意味着你需要确保App Startup首先初始化WorkManager。定义一个实现Initializer< examplelogger>的ExampleLoggerInitializer类:

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

因为在dependencies()方法中包含了WorkManagerInitializer,所以App Startup会在初始化ExampleLogger之前初始化WorkManager。

设置清单条目 Set up manifest entries

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

这意味着为了让应用启动能够发现一个组件初始化器,必须满足以下条件之一: 1.组件初始化器在InitializationProvider清单条目下有一个相应的<meta-data>条目。 2.组件初始化器在dependencies()方法中列出,该方法来自一个已经可以发现的初始化器。

再次考虑带有WorkManagerInitializer和ExampleLoggerInitializer的示例。为了确保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"属性确保清单合并工具能够正确地解决任何冲突条目。

运行检查

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

手动初始化组件 Manually initialize components

通常,当你使用App Startup时,InitializationProvider对象使用一个名为AppInitializer的实体来自动发现并在应用启动时运行组件初始化器。 然而,你也可以直接使用AppInitializer来手动初始化应用启动时不需要的组件。这被称为延迟初始化,它可以帮助最小化启动成本。

您必须首先禁用手动初始化的任何组件的自动初始化。

禁用单个组件的自动初始化 tools:node="remove"

要禁用单个组件的自动初始化,请从清单中删除该组件初始化器的<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>

<meta-data>中使用工具:node="remove",而不是简单地删除条目,以确保合并工具也从所有其他合并的清单文件中删除条目。

禁用所有组件的自动初始化

要禁用所有自动初始化,请从清单中删除InitializationProvider的整个条目:

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

手动调用组件初始化器

如果一个组件的自动初始化被禁用,您可以使用AppInitializer 来手动初始化该组件及其依赖项。

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

因此,应用程序启动也会初始化WorkManager,因为WorkManager是Example的依赖。

如果初始化器里面的create方法,还是会造成启动慢的,

初始化器初始完成后,才执行 Application onCreate

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