Android Jetpack系列之应用初始化 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)