Запуск приложения . Часть Android Jetpack .

Библиотека запуска приложений предоставляет простой и эффективный способ инициализации компонентов при запуске приложения. Как разработчики библиотек, так и разработчики приложений могут использовать App Startup для оптимизации последовательности запуска и явного задания порядка инициализации.

Вместо определения отдельных поставщиков контента для каждого компонента, который необходимо инициализировать, App Startup позволяет вам определять инициализаторы компонентов, которые используют одного поставщика контента. Это может значительно сократить время запуска приложения.

Настраивать

Чтобы использовать запуск Jetpack в своей библиотеке или приложении, добавьте в файл Gradle следующее:

классный

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

Котлин

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

Инициализировать компоненты при запуске приложения

Приложения и библиотеки часто полагаются на инициализацию компонентов сразу при запуске приложения. Вы можете удовлетворить эту потребность, используя поставщиков контента для инициализации каждой зависимости, но создание экземпляров поставщиков контента является дорогостоящим и может излишне замедлить последовательность запуска. Кроме того, Android инициализирует поставщиков контента в неопределенном порядке. Запуск приложения обеспечивает более эффективный способ инициализации компонентов при запуске приложения и явного определения их зависимостей.

Чтобы использовать запуск приложения для автоматической инициализации компонентов при запуске, необходимо определить инициализатор компонента для каждого компонента, который приложение должно инициализировать.

Реализация инициализаторов компонентов

Вы определяете инициализатор каждого компонента, создавая класс, реализующий интерфейс Initializer<T> . Этот интерфейс определяет два важных метода:

  • Метод create() , который содержит все необходимые операции для инициализации компонента и возвращает экземпляр T
  • Метод dependencies() , который возвращает список других объектов Initializer<T> , от которых зависит инициализатор. Этот метод можно использовать для управления порядком, в котором приложение запускает инициализаторы при запуске.

Например, предположим, что ваше приложение зависит от WorkManager и его необходимо инициализировать при запуске. Определите класс WorkManagerInitializer , который реализует Initializer<WorkManager> :

Котлин

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

Ява

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

}

Метод dependencies() возвращает пустой список, поскольку WorkManager не зависит ни от каких других библиотек.

Предположим, что ваше приложение также зависит от библиотеки ExampleLogger , которая, в свою очередь, зависит от WorkManager . Эта зависимость означает, что вам необходимо убедиться, что при запуске приложения сначала инициализируется WorkManager . Определите класс ExampleLoggerInitializer , который реализует Initializer<ExampleLogger> :

Котлин

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

Ява

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

Поскольку вы включаете WorkManagerInitializer в метод dependencies() , при запуске приложения WorkManager инициализируется перед ExampleLogger .

Настройка записей манифеста

App Startup включает в себя специальный поставщик контента, называемый InitializationProvider , который используется для обнаружения и вызова инициализаторов компонентов. Запуск приложения обнаруживает инициализаторы компонентов, сначала проверяя наличие записи <meta-data> в записи манифеста InitializationProvider . Затем запуск приложения вызывает методы dependencies() для любых инициализаторов, которые он уже обнаружил.

Это означает, что для того, чтобы инициализатор компонента мог быть обнаружен при запуске приложения, должно быть выполнено одно из следующих условий:

  • Инициализатор компонента имеет соответствующую запись <meta-data> в записи манифеста InitializationProvider .
  • Инициализатор компонента указан в методе dependencies() из инициализатора, который уже доступен для обнаружения.

Рассмотрим еще раз пример с WorkManagerInitializer и ExampleLoggerInitializer . Чтобы убедиться, что запуск приложения может обнаружить эти инициализаторы, добавьте в файл манифеста следующее:

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

Вам не нужно добавлять запись <meta-data> для WorkManagerInitializer , поскольку WorkManagerInitializer является зависимостью от ExampleLoggerInitializer . Это означает, что если ExampleLoggerInitializer доступен для обнаружения, то и WorkManagerInitializer тоже.

Атрибут tools:node="merge" гарантирует, что инструмент слияния манифестов правильно разрешает любые конфликтующие записи.

Запуск проверки ворса

Библиотека запуска приложений включает набор правил проверки, которые вы можете использовать, чтобы проверить, правильно ли вы определили инициализаторы компонентов. Вы можете выполнить эти проверки, запустив ./gradlew :app:lintDebug из командной строки.

Инициализируйте компоненты вручную

Обычно при использовании запуска приложения объект InitializationProvider использует сущность AppInitializer для автоматического обнаружения и запуска инициализаторов компонентов при запуске приложения. Однако вы также можете использовать AppInitializer напрямую, чтобы вручную инициализировать компоненты, которые не нужны вашему приложению при запуске. Это называется ленивой инициализацией и может помочь минимизировать затраты на запуск.

Сначала необходимо отключить автоматическую инициализацию для всех компонентов, которые вы хотите инициализировать вручную.

Отключить автоматическую инициализацию для отдельного компонента

Чтобы отключить автоматическую инициализацию для одного компонента, удалите запись <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>

Вы используете в записи tools:node="remove" вместо простого удаления записи, чтобы гарантировать, что инструмент слияния также удалит запись из всех других объединенных файлов манифеста.

Отключить автоматическую инициализацию для всех компонентов

Чтобы отключить всю автоматическую инициализацию, удалите всю запись для InitializationProvider из манифеста:

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

Ручной вызов инициализаторов компонентов

Если для компонента отключена автоматическая инициализация, вы можете использовать AppInitializer для ручной инициализации этого компонента и его зависимостей.

Например, следующий код вызывает AppInitializer и вручную инициализирует ExampleLogger :

Котлин

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

Ява

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

В результате запуск приложения также инициализирует WorkManager , поскольку WorkManager является зависимостью от ExampleLogger .

Оставьте отзыв

Поделитесь с нами своими отзывами и идеями через эти ресурсы:

Трекер проблем
Сообщайте о проблемах, чтобы мы могли исправить ошибки.
{% дословно %} {% дословно %} {% дословно %} {% дословно %}