Inicio de apps Parte de Android Jetpack.

La biblioteca de App Startup proporciona una forma sencilla y eficaz de inicializar componentes cuando se inicia una aplicación. Tanto los desarrolladores de bibliotecas como los de apps pueden usar App Startup para optimizar las secuencias de inicio y establecer de forma explícita el orden de inicialización.

En lugar de definir proveedores de contenido separados para cada componente que necesitas inicializar, App Startup te permite definir inicializadores de componentes que comparten un solo proveedor de contenido. Esto puede acelerar en gran medida el tiempo de inicio de la app.

Configuración

Para usar Jetpack Startup en tu biblioteca o app, agrega lo siguiente a tu archivo Gradle:

Groovy

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

Kotlin

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

Inicializa componentes cuando se inicia la app

A menudo, las apps y bibliotecas dependen de que los componentes se inicialicen de inmediato cuando se inicia la app. Puedes satisfacer esta necesidad si usas proveedores de contenido para inicializar cada dependencia, pero es costoso crear instancias de proveedores de contenido y pueden ralentizar la secuencia de inicio innecesariamente. Además, Android inicializa los proveedores de contenido en un orden indeterminado. App Startup proporciona una forma más eficaz de inicializar componentes cuando se abre una app y definir sus dependencias de forma explícita.

Si deseas usar App Startup para inicializar componentes automáticamente al inicio, debes definir un inicializador de componente para cada componente que la app necesite inicializar.

Implementa inicializadores de componentes

Para definir el inicializador de cada componente, crea una clase que implemente la interfaz Initializer<T>. Esta interfaz define dos métodos importantes:

  • El método create(), que contiene todas las operaciones necesarias para inicializar el componente y muestra una instancia de T
  • El método dependencies(), que muestra una lista de los otros objetos Initializer<T> de los que depende el inicializador Puedes usar este método para controlar el orden en que la app ejecuta los inicializadores en el inicio.

Por ejemplo, supongamos que tu app depende de WorkManager y necesita inicializarla al inicio. Define una clase WorkManagerInitializer que implemente Initializer<WorkManager>:

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

}

El método dependencies() muestra una lista vacía porque WorkManager no depende de otras bibliotecas.

Supongamos que tu app también depende de una biblioteca llamada ExampleLogger, que a su vez depende de WorkManager. Esta dependencia significa que debes asegurarte de que App Startup inicialice WorkManager. Define una clase ExampleLoggerInitializer que implemente Initializer<ExampleLogger>:

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

Debido a que incluyes WorkManagerInitializer en el método dependencies(), App Startup inicializa WorkManager antes de ExampleLogger.

Cómo configurar entradas de manifiesto

App Startup incluye un proveedor de contenido especial llamado InitializationProvider que usa para descubrir y llamar a los inicializadores de tus componentes. Para descubrir los inicializadores de componentes, App Startup busca primero una entrada <meta-data> en la entrada de manifiesto InitializationProvider. Luego, App Startup llama a los métodos dependencies() para cualquier inicializador que ya haya descubierto.

Esto significa que, para que App Startup pueda detectar el inicializador de un componente, se debe cumplir una de las siguientes condiciones:

  • El inicializador de componentes tiene una entrada <meta-data> correspondiente en la entrada InitializationProvider del manifiesto.
  • El inicializador del componente aparece en el método dependencies() a partir de un inicializador que ya es detectable.

Considera de nuevo el ejemplo con WorkManagerInitializer y ExampleLoggerInitializer. Para asegurarte de que App Startup pueda detectar estos inicializadores, agrega lo siguiente al archivo de manifiesto:

<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>

No es necesario que agregues una entrada <meta-data> para WorkManagerInitializer, ya que WorkManagerInitializer es una dependencia de ExampleLoggerInitializer. Esto significa que si ExampleLoggerInitializer es detectable, también lo es WorkManagerInitializer.

El atributo tools:node="merge" garantiza que la herramienta de combinación de manifiestos resuelva correctamente cualquier entrada en conflicto.

Ejecutar comprobaciones de lint

En la biblioteca de App Startup, se incluye un conjunto de reglas de lint que puedes usar para comprobar si definiste correctamente los inicializadores de tus componentes. Para realizar estas comprobaciones de lint, puedes ejecutar ./gradlew :app:lintDebug desde la línea de comandos.

Inicializa componentes de forma manual

Por lo general, cuando usas App Startup, el objeto InitializationProvider usa una entidad llamada AppInitializer para descubrir y ejecutar automáticamente los inicializadores de componentes cuando se inicia la aplicación. Sin embargo, también puedes usar AppInitializer directamente para inicializar de forma manual componentes que tu app no necesite en el inicio. Esto se denomina inicialización diferida y puede ayudar a minimizar los costos de inicio.

Primero, debes inhabilitar la inicialización automática de cualquier componente que desees inicializar de forma manual.

Inhabilita la inicialización automática para un componente individual

Para inhabilitar la inicialización automática de un solo componente, quita del manifiesto la entrada <meta-data> del inicializador de ese componente.

Por ejemplo, si agregas lo siguiente al archivo de manifiesto, se inhabilita la inicialización automática de 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>

Usas tools:node="remove" en la entrada en lugar de solo quitarla para asegurarte de que la herramienta de combinación también la quite de todos los demás archivos de manifiesto combinados.

Inhabilitar la inicialización automática para todos los componentes

Para inhabilitar por completo la inicialización automática, quita la entrada completa de InitializationProvider del manifiesto:

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

Cómo llamar de forma manual a los inicializadores de componentes

Si la inicialización automática está inhabilitada para un componente, puedes usar AppInitializer a fin de inicializar de forma manual ese componente y sus dependencias.

Por ejemplo, el siguiente código llama a AppInitializer e inicializa ExampleLogger de forma manual:

Kotlin

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

Java

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

Como resultado, App Startup también inicializa WorkManager porque WorkManager es una dependencia de ExampleLogger.

Envía comentarios

Usa estos recursos para compartir tus comentarios y tus ideas con nosotros:

Herramienta de seguimiento de errores
Informa los problemas para que podamos corregir los errores.