App Startup Extension is a library based on AndroidX App Startup that optimizes component initialization in Android applications using Kotlin Coroutines. Its primary goal is to improve startup time without blocking the main thread.
- Synchronous Initialization: Allows components to be initialized synchronously.
- Asynchronous Initialization: Supports asynchronous component initialization to avoid blocking the main thread.
To add this library to your Android project, include the repository in your project-level
build.gradle file:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
}
}Then, add the dependency in your module-level build.gradle file:
dependencies {
implementation("io.github.santimattius.android:app-startup-extension:${version}")
Replace version with the desired library version.
To define an initializer, implement StartupSyncInitializer or StartupAsyncInitializer.
class SyncTestInitializer : StartupSyncInitializer<Unit> {
override fun create(context: Context) {
Log.d("SyncTestInitializer", "TestInitializer created")
}
}Note:
StartupSyncInitializerruns on the main thread during app startup.
class AsyncTestInitializer : StartupAsyncInitializer<Unit> {
override suspend fun create(context: Context) {
Log.d("AsyncTestInitializer", "AsyncTestInitializer start")
delay(5000)
Log.d("AsyncTestInitializer", "AsyncTestInitializer end")
}
}<provider android:authorities="${applicationId}.startup-extension" android:exported="false"
android:name="io.github.santimattius.android.startup.InitializationProvider" tools:node="merge">
<meta-data android:name="com.santimattius.android.sample.SyncTestInitializer"
android:value="sync-initializer" />
<meta-data android:name="com.santimattius.android.sample.AsyncTestInitializer"
android:value="async-initializer" />
</provider>You can also manually initialize components:
val initializer = AppStartupInitializer.getInstance(this@MainActivity)
// Synchronous initialization
initializer.doInitialize<Unit>(SyncTestInitializer::class.java)
// Asynchronous initialization
coroutineScope.launch {
initializer.doInitialize<Unit>(AsyncTestInitializer::class.java)
}This function suspends execution until all asynchronous initialization tasks started by AppStartupInitializer are completed. It ensures that any background startup operations, such as data preloading or library initialization, finish before proceeding.
val appStartupInitializer = AppStartupInitializer.getInstance(appContext)
coroutineScope.launch {
appStartupInitializer.awaitAllStartJobs()
}
Executes a given block of code only after all startup jobs have finished. This is useful for running code that depends on the completion of initialization processes.
coroutineScope.launch {
appStartupInitializer.onAppStartupLaunched {
Log.d("AppStartup", "All initialization tasks completed")
}
}Checks if all initialization jobs managed by AppStartupInitializer are completed. It returns true if no jobs are currently active, otherwise false.
if (appStartupInitializer.isAllStartedJobsDone()) {
Log.d("AppStartup", "All startup jobs have finished")
}If you are already using AndroidX App Startup, follow these steps to migrate to App Startup Extension:
-
Modify
AndroidManifest.xml:Before:
<provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge" > <!-- This entry makes ExampleLoggerInitializer discoverable. --> </provider>
After:
<provider android:name="io.github.santimattius.android.startup.InitializationProvider" android:authorities="${applicationId}.app-startup-extension" android:exported="false" tools:node="merge" > <!-- This entry makes ExampleLoggerInitializer discoverable. --> </provider>
-
Change the
meta-datavalue fromandroidx.startuptosync-initializer.<provider android:name="io.github.santimattius.android.startup.InitializationProvider" android:authorities="${applicationId}.app-startup-extension" android:exported="false" tools:node="merge"> <!-- This entry makes ExampleLoggerInitializer discoverable. --> <meta-data android:name="com.santimattius.android.sample.migration.ExampleLoggerInitializer" android:value="sync-initializer" /> </provider>
-
Modify the
Initializerimplementation:Before:
import androidx.startup.Initializer class ExampleLoggerInitializer : Initializer<Unit> { override fun create(context: Context) { // Initialization code } override fun dependencies(): List<Class<out Initializer<*>>> = emptyList() }
After:
import io.github.santimattius.android.startup.initializer.StartupSyncInitializer class ExampleLoggerInitializer : StartupSyncInitializer<Unit> { override fun create(context: Context) { // Initialization code } override fun dependencies(): List<Class<out StartupSyncInitializer<*>>> = emptyList() }
Contributions are welcome! To contribute to this library, follow these steps:
- Fork the repository.
- Create a new branch for your contribution (
git checkout -b feature/new-feature). - Implement your changes following the style guides and coding conventions.
- Commit your changes with a clear description (
git commit -am 'Add new feature'). - Push your changes to your repository (
git push origin feature/new-feature). - Create a pull request on GitHub, describing your changes.
If you have questions, issues, or suggestions about this library, feel free to open an issue on GitHub. We are here to help!
