Uruchamianie aplikacji Część pakietu Android Jetpack.

Biblioteka uruchamiania aplikacji zapewnia prosty i skuteczny sposób inicjowania komponentów podczas uruchamiania aplikacji. Zarówno deweloperzy bibliotek, jak i deweloperzy aplikacji mogą korzystać z uruchamiania aplikacji, aby uprościć sekwencje uruchamiania i jawnie określić kolejność inicjowania.

Zamiast definiować osobne dostawców treści dla każdego komponentu, który musisz zainicjować, funkcja uruchamiania aplikacji umożliwia definiowanie inicjatorów komponentów mających jednego dostawcę treści. Może to znacznie skrócić czas uruchamiania aplikacji.

Skonfiguruj

Aby użyć Jetpack Startup w bibliotece lub aplikacji, dodaj do pliku Gradle ten kod:

Odlotowy

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

Kotlin

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

Inicjowanie komponentów podczas uruchamiania aplikacji

Komponenty w aplikacjach i bibliotekach są często uruchamiane natychmiast po uruchomieniu. Aby zaspokoić tę potrzebę, możesz skorzystać z usług dostawców treści do zainicjowania każdej zależności, ale utworzenie instancji przez dostawców treści jest kosztowne i może niepotrzebnie spowolnić sekwencję uruchamiania. Dodatkowo Android inicjuje dostawców treści w nieokreślonej kolejności. Uruchamianie aplikacji zapewnia wydajniejszy sposób inicjowania komponentów podczas uruchamiania aplikacji i jawnego definiowania ich zależności.

Aby automatycznie inicjować komponenty przy uruchomieniu aplikacji, musisz zdefiniować inicjator każdego komponentu, który musi zainicjować aplikacja.

Implementowanie inicjatorów komponentów

Aby zdefiniować każdy inicjator komponentów, musisz utworzyć klasę, która implementuje interfejs Initializer<T>. Ten interfejs definiuje 2 ważne metody:

  • Metoda create(), która zawiera wszystkie operacje niezbędne do zainicjowania komponentu i zwraca wystąpienie T.
  • Metoda dependencies(), która zwraca listę innych obiektów Initializer<T>, od których zależy inicjator. Za pomocą tej metody możesz kontrolować kolejność uruchamiania inicjatorów przez aplikację podczas uruchamiania.

Załóżmy na przykład, że aplikacja zależy od WorkManager i musi ją zainicjować przy uruchamianiu. Zdefiniuj klasę WorkManagerInitializer, która implementuje 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();
    }

}

Metoda dependencies() zwraca pustą listę, ponieważ WorkManager nie zależy od innych bibliotek.

Załóżmy, że Twoja aplikacja zależy też od biblioteki o nazwie ExampleLogger, która z kolei zależy od biblioteki WorkManager. Ta zależność oznacza, że najpierw musisz się upewnić, że uruchamianie aplikacji zainicjuje WorkManager. Zdefiniuj klasę ExampleLoggerInitializer, która implementuje 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);
    }
}

Ponieważ w metodzie dependencies() uwzględnisz WorkManagerInitializer, Startup aplikacji inicjuje WorkManager przed ExampleLogger.

Konfigurowanie wpisów w pliku manifestu

App Startup korzysta ze specjalnego dostawcy treści o nazwie InitializationProvider, którego używa do wykrywania i wywoływania inicjatorów komponentów. Uruchamianie aplikacji wykrywa inicjatory komponentów, sprawdzając najpierw wpis <meta-data> we wpisie w pliku manifestu InitializationProvider. Następnie uruchamianie aplikacji wywołuje metody dependencies() w przypadku wszystkich inicjatorów, które zostały już wykryte.

Oznacza to, że aby inicjator komponentu był wykrywalny przez aplikację App Startup, musi być spełniony jeden z tych warunków:

  • Inicjator komponentu ma odpowiedni wpis <meta-data> w pliku manifestu InitializationProvider.
  • Inicjator komponentu jest wymieniony w metodzie dependencies() w inicjatorze, który jest już wykrywalny.

Przeanalizujmy jeszcze raz przykład z elementami WorkManagerInitializer i ExampleLoggerInitializer. Aby mieć pewność, że aplikacja startowa będzie mogła wykrywać te inicjatory, dodaj do pliku manifestu ten kod:

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

Nie musisz dodawać wpisu <meta-data> dla WorkManagerInitializer, ponieważ WorkManagerInitializer to zależność ExampleLoggerInitializer. Oznacza to, że jeśli element ExampleLoggerInitializer jest wykrywalny, to WorkManagerInitializer też jest.

Atrybut tools:node="merge" zapewnia, że narzędzie do łączenia plików manifestu prawidłowo rozwiązuje konflikty wpisów.

Uruchom sprawdzanie lintowań

Biblioteka uruchamiania aplikacji zawiera zestaw reguł lintowania, za pomocą których można sprawdzić, czy inicjatory komponentów zostały prawidłowo zdefiniowane. Te testy lintowania możesz przeprowadzić, uruchamiając polecenie ./gradlew :app:lintDebug z poziomu wiersza poleceń.

Ręczne inicjowanie komponentów

Zwykle podczas uruchamiania aplikacji obiekt InitializationProvider używa encji o nazwie AppInitializer, aby automatycznie wykrywać i uruchamiać inicjatory komponentów podczas uruchamiania aplikacji. Możesz też jednak użyć bezpośrednio AppInitializer, by ręcznie inicjować komponenty, których aplikacja nie potrzebuje przy uruchamianiu. Jest to tzw. leniwe inicjowanie, które pozwala zminimalizować koszty uruchamiania.

Musisz najpierw wyłączyć automatyczne inicjowanie wszystkich komponentów, które chcesz inicjować ręcznie.

Wyłączanie automatycznego inicjowania pojedynczego komponentu

Aby wyłączyć automatyczne inicjowanie pojedynczego komponentu, usuń z pliku manifestu wpis <meta-data> dotyczący inicjatora tego komponentu.

Na przykład dodanie tego kodu do pliku manifestu wyłączy automatyczne inicjowanie usługi 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>

Zamiast po prostu usunąć wpis, użyj w nim tools:node="remove", aby mieć pewność, że narzędzie do scalania również usunie wpis ze wszystkich innych scalonych plików manifestu.

Wyłącz automatyczne inicjowanie wszystkich komponentów

Aby wyłączyć całe automatyczne inicjowanie, usuń z pliku manifestu cały wpis dotyczący InitializationProvider:

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

Ręczne wywoływanie inicjatorów komponentów

Jeśli automatyczne inicjowanie komponentu jest wyłączone, możesz ręcznie zainicjować ten komponent i jego zależności za pomocą AppInitializer.

Na przykład ten kod wywołuje funkcję AppInitializer i ręcznie inicjuje ExampleLogger:

Kotlin

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

Java

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

W efekcie uruchamianie aplikacji inicjuje również WorkManager, ponieważ WorkManager jest zależność typu ExampleLogger.

Prześlij opinię

Podziel się z nami swoją opinią i pomysłami, korzystając z tych zasobów:

Śledzenie problemów
Zgłoś problemy, żebyśmy mogli naprawić błędy.