Inicialização do app Parte do Android Jetpack.

A biblioteca App Startup fornece uma maneira simples e eficiente de iniciar componentes na inicialização do aplicativo. Tanto os desenvolvedores de bibliotecas quanto os desenvolvedores de apps podem usar a inicialização para simplificar as sequências e definir explicitamente a ordem de inicialização.

Em vez de definir provedores de conteúdo separados para cada componente que você precisa inicializar, a inicialização do app permite definir inicializadores de componentes que compartilham um único provedor de conteúdo. Isso melhora significativamente o tempo de inicialização do app.

Configurar

Para usar o Jetpack Startup na sua biblioteca ou app, adicione o código abaixo ao arquivo Gradle:

Groovy

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

Kotlin

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

Inicializar componentes na inicialização do app

Apps e bibliotecas geralmente dependem da inicialização de componentes imediatamente quando o app é iniciado. É possível atender a essa necessidade usando provedores de conteúdo para inicializar cada dependência, mas eles são caros de instanciar e podem atrasar a sequência de inicialização desnecessariamente. Além disso, o Android inicializa provedores de conteúdo em uma ordem indeterminada. A inicialização do app oferece uma maneira mais eficiente de inicializar componentes na inicialização do app e definir explicitamente as dependências deles.

Para usar a inicialização do app para inicializar componentes automaticamente na inicialização, é necessário definir um inicializador de componente para cada componente que o app precisa inicializar.

Implementar inicializadores de componente

Para definir cada inicializador de componente, crie uma classe que implemente a interface Initializer<T>. Essa interface define dois métodos importantes:

  • O método create(), que contém todas as operações necessárias para inicializar o componente e retorna uma instância de T.
  • O método dependencies(), que retorna uma lista dos outros objetos Initializer<T> de que o inicializador depende. Você pode usar esse método para controlar a ordem em que o app executa os inicializadores na inicialização.

Por exemplo, suponha que seu app dependa de WorkManager e precise inicializá-lo na inicialização. Defina uma classe 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();
    }

}

O método dependencies() retorna uma lista vazia porque WorkManager não depende de outras bibliotecas.

Suponha que seu app também dependa de uma biblioteca com o nome ExampleLogger, que, por sua vez, depende de WorkManager. Essa dependência significa que você precisa garantir que a inicialização do app inicialize WorkManager primeiro. Defina uma classe 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);
    }
}

Como você inclui WorkManagerInitializer no método dependencies(), a inicialização do app inicializa o WorkManager antes de ExampleLogger.

Configurar entradas de manifesto

A inicialização do app inclui um provedor de conteúdo especial chamado InitializationProvider, que ele usa para descobrir e chamar os inicializadores de componentes. A inicialização do app descobre inicializadores de componentes ao verificar primeiro se há uma entrada <meta-data> na entrada de manifesto InitializationProvider. Em seguida, a inicialização do app chama os métodos dependencies() para qualquer inicializador que já tenha sido descoberto.

Isso significa que, para que um inicializador de componente seja detectável pela inicialização do app, uma das seguintes condições precisa ser atendida:

  • O inicializador do componente tem uma entrada <meta-data> correspondente na entrada do manifesto InitializationProvider.
  • O inicializador de componente é listado no método dependencies() de um inicializador que já é detectável.

Considere novamente o exemplo com WorkManagerInitializer e ExampleLoggerInitializer. Para garantir que a inicialização do app possa detectar esses inicializadores, adicione o seguinte ao arquivo de manifesto:

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

Não é necessário adicionar uma entrada <meta-data> para WorkManagerInitializer, porque WorkManagerInitializer é uma dependência de ExampleLoggerInitializer. Isso significa que, se ExampleLoggerInitializer for detectável, WorkManagerInitializer também será.

O atributo tools:node="merge" garante que a ferramenta de combinação de manifestos resolva corretamente todas as entradas conflitantes.

Executar verificações de lint

A biblioteca App Startup inclui um conjunto de regras de lint que podem ser usadas para verificar se você definiu os inicializadores de componentes corretamente. Você pode realizar essas verificações de lint executando ./gradlew :app:lintDebug na linha de comando.

Inicializar componentes manualmente

Normalmente, ao usar a inicialização do app, o objeto InitializationProvider usa uma entidade chamada AppInitializer para descobrir e executar automaticamente inicializadores de componentes na inicialização do aplicativo. No entanto, você também pode usar AppInitializer diretamente para inicializar manualmente componentes que não são necessários para o app na inicialização. Isso é chamado de inicialização lenta e pode ajudar a minimizar os custos de inicialização.

Primeiro, desative a inicialização automática de todos os componentes que você quiser inicializar manualmente.

Desativar a inicialização automática de um componente individual

Para desativar a inicialização automática de um único componente, remova do manifesto a entrada <meta-data> do inicializador desse componente.

Por exemplo, adicionar o código abaixo ao arquivo de manifesto desativa a inicialização 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>

Use tools:node="remove" na entrada em vez de simplesmente remover a entrada para garantir que a ferramenta de combinação também remova a entrada de todos os outros arquivos de manifesto integrados.

Desativar a inicialização automática para todos os componentes

Para desativar toda a inicialização automática, remova toda a entrada de InitializationProvider do manifesto:

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

Chamar inicializadores de componente manualmente

Se a inicialização automática estiver desativada para um componente, será possível usar AppInitializer para inicializar manualmente esse componente e as dependências dele.

Por exemplo, o código a seguir chama AppInitializer e inicializa manualmente ExampleLogger:

Kotlin

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

Java

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

Como resultado, a Inicialização do app também inicializa WorkManager porque WorkManager é uma dependência de ExampleLogger.

Enviar feedback

Envie comentários e ideias usando os recursos abaixo:

Issue tracker
Informe os problemas para que possamos corrigir os bugs.