Настройка Dynamic Feature Modules для Android-приложения

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Настройка Dynamic Feature Modules для Android-приложения
Сложная
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    445

Настройка Dynamic Feature Modules для Android-приложения

Приложение для доставки еды имеет встроенный модуль AR-просмотра блюд — весит 23 MB дополнительных ресурсов. Эту функцию открывают 8% пользователей. Остальные 92% скачивают 23 MB, которые им не нужны никогда. Dynamic Feature Modules решает именно это: AR-модуль скачивается только тем, кто нажал «посмотреть в AR».

Архитектура проекта с DFM

Проект перестраивается на multi-module структуру. app становится base модулем — содержит только критичный для старта функционал. Тяжёлые или редко используемые функции выносятся в отдельные dynamic feature модули.

Структура build.gradle для DFM:

// dynamic feature module build.gradle
plugins {
    id("com.android.dynamic-feature")
}

android {
    defaultConfig { minSdk = 21 }
}

dependencies {
    implementation(project(":app")) // зависимость от base module
}

В app/build.gradle:

android {
    dynamicFeatures += setOf(":feature_ar", ":feature_premium")
}

Три режима установки

Install-time (dist:install-time) — модуль устанавливается вместе с приложением. Разница с обычным модулем в том, что он может поставляться как separate APK и участвует в слайсинге.

On-demand (dist:on-demand) — загружается по запросу через Play Feature Delivery API:

val manager = SplitInstallManagerFactory.create(context)
val request = SplitInstallRequest.newBuilder()
    .addModule("feature_ar")
    .build()

manager.startInstall(request)
    .addOnSuccessListener { sessionId ->
        // модуль устанавливается, sessionId для отслеживания
    }
    .addOnFailureListener { exception ->
        // SplitInstallException — обрабатываем коды ошибок
    }

Conditional (dist:conditions) — автоматическая установка при соответствии условиям: версия Android, наличие OpenGL ES, страна пользователя.

Проблемы при внедрении

Навигация. Из базового модуля нельзя импортировать классы из DFM напрямую (циклическая зависимость). Навигация строится через Intent с explicit class name как строкой или через Navigation Component с include-dynamic. @Navigator с DynamicNavHostFragment — правильный способ для Jetpack Navigation:

<navigation>
    <include-dynamic
        android:id="@+id/ar_graph"
        android:name="com.example.feature_ar"
        app:moduleName="feature_ar"
        app:graphResId="@navigation/ar_navigation" />
</navigation>

SplitCompat. Для доступа к ресурсам и классам установленного DFM нужно включить SplitCompat в Application:

override fun attachBaseContext(base: Context) {
    super.attachBaseContext(base)
    SplitCompat.install(this)
}

Без этого ClassNotFoundException при попытке использовать класс из только что установленного модуля — распространённая ошибка.

Тестирование. DFM не работают на обычном APK-сборке — только при установке через Play Store или через bundletool. Для локальной разработки используем bundletool install-apks или internal testing track в Play Console. Написать тест без учёта этого ограничения — потерять день.

Состояние сессии. SplitInstallSessionState проходит через несколько состояний: PENDING → DOWNLOADING → INSTALLING → INSTALLED. При размере модуля больше 10 MB Google требует показать пользователю диалог подтверждения (SplitInstallException с кодом REQUIRES_USER_CONFIRMATION). Обрабатывать обязательно, иначе установка молча прерывается.

Кейс: навигация через DFM без Jetpack Navigation

В проекте на базе кастомного Router пришлось реализовать lazy-loading модулей без Jetpack Navigation. Решение: интерфейс FeatureProvider в base-модуле, реализация в DFM через ServiceLocator. DFM регистрирует свой FeatureProvider при загрузке через reflection (единственный случай где это оправдано — именно для DFM bootstrapping). Base-модуль запрашивает FeatureProvider через SplitInstallManager.installedModules.

Что проверяем при настройке

  • Граф зависимостей: DFM зависит от base, никогда наоборот
  • SplitCompat инициализирован во всех Application/Activity
  • Все DFM-сценарии покрыты обработкой REQUIRES_USER_CONFIRMATION
  • Bundletool-тест на реальных устройствах перед публикацией
  • Deferred install для некритичных модулей — не блокируем пользователя

Сроки

Настройка одного DFM-модуля с навигацией — 3–5 дней. Перевод существующего монолитного приложения на multi-module с несколькими DFM — 2–4 недели в зависимости от сцепленности кода.