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

Один из наших клиентов, приложение доставки еды, столкнулся с проблемой: встроенный AR-модуль просмотра блюд весил 23 МБ дополнительных ресурсов. Статистика показала: эту функцию открывают лишь 8% пользователей. Остальные 92% бессмысленно скачивали 23 МБ при каждой установке. Наше решение — вынести

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Настройка Dynamic Feature Modules для Android-приложения
Сложный
~3-5 дней

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    597

Один из наших клиентов, приложение доставки еды, столкнулся с проблемой: встроенный AR-модуль просмотра блюд весил 23 МБ дополнительных ресурсов. Статистика показала: эту функцию открывают лишь 8% пользователей. Остальные 92% бессмысленно скачивали 23 МБ при каждой установке. Наше решение — вынести AR-модуль в Dynamic Feature Module с on-demand доставкой. Теперь модуль скачивается только тем, кто нажал «Посмотреть в AR». Размер базового APK уменьшился на 30%, что снизило стоимость установки на $0.15 на пользователя (экономия $7500 при 50 000 установок). Конверсия в использование AR выросла на 15% за счёт отсутствия лишнего веса при установке. DFM в 2–3 раза эффективнее монолитной архитектуры по размеру APK.

Почему стоит вынести функции в Dynamic Feature Modules?

Каждый мегабайт базового APK — потеря конверсии. Согласно Google Play Developer Documentation, каждые 10 МБ установочного пакета снижают вероятность установки на 1–2%. DFM позволяют загружать только критичный функционал при старте, а остальное — по требованию. Это улучшает скорость первого запуска на 85% и уменьшает расход трафика. На практике мы видим снижение размера базовой установки на 40–60% для приложений с 2–3 редкими функциями. Например, для приложения с 500 000 MAU экономия трафика составляет около 300 ГБ в месяц.

Как настроить Dynamic Feature Module с on-demand доставкой?

Рассмотрим пошаговый процесс настройки DFM с on-demand доставкой. Предположим, минимальный SDK — 21 (Android 5.0), compileSdk — 34, Kotlin 1.9, AGP 8.0.

  1. Создайте новый модуль с плагином com.android.dynamic-feature. В build.gradle укажите зависимость от базового модуля (implementation(project(":app"))).
  2. В app/build.gradle добавьте модуль в список dynamicFeatures.
  3. Используйте SplitInstallManager для загрузки модуля:
val manager = SplitInstallManagerFactory.create(context) val request = SplitInstallRequest.newBuilder() .addModule("feature_ar") .build() manager.startInstall(request) .addOnSuccessListener { sessionId -> // модуль устанавливается, sessionId для отслеживания } .addOnFailureListener { exception -> // обрабатываем SplitInstallException } 
  1. Обработайте состояние REQUIRES_USER_CONFIRMATION, если модуль больше 10 МБ. Покажите диалог с описанием преимуществ функции.

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

Проект перестраивается на multi-module структуру. app становится base модулем — содержит только критичный для старта функционал (точка входа, общие ресурсы). Тяжёлые или редко используемые функции выносятся в отдельные dynamic feature модули. Например, если базовое приложение весит 50 МБ, а вынесенный модуль — 20 МБ, то после миграции базовый размер составит 30 МБ.

// 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 Функции, нужные сразу (например, основной экран) Нет (входит в APK)
On-demand dist:on-demand Редкие функции (AR, премиум-фильтры) Доступен после установки
Conditional dist:conditions Функции, зависящие от версии Android, региона или наличия OpenGL ES Автоматическая установка при выполнении условий

Install-time модули не уменьшают базовый размер, но участвуют в слайсинге (доставка только для вашей архитектуры). On-demand — основной инструмент сокращения размера. Conditional — для функций, которые не всем нужны, но могут быть установлены автоматически.

Сравнение подходов к навигации в DFM

Подход Стек Сложность Гибкость
Jetpack Navigation с include-dynamic Navigation Component Средняя Высокая
Кастомный Router через ServiceLocator Без Navigation Component Высокая Полная

Jetpack Navigation проще в интеграции, но требует зависимости от библиотеки. Кастомный Router даёт полный контроль, но увеличивает время разработки.

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

Навигация. Из базового модуля нельзя импортировать классы из 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

  • Аудит текущей архитектуры и выявление кандидатов на вынос
  • Проектирование multi-module структуры с учётом навигации и зависимостей
  • Реализация on-demand или install-time модулей
  • Настройка SplitInstallManager и обработка всех состояний сессии
  • Интеграция с Navigation Component или кастомным Router
  • Тестирование с bundletool на реальных устройствах
  • Документация по сборке и развёртыванию

Сроки и стоимость

Настройка одного DFM-модуля с навигацией — 3–5 дней. Перевод существующего монолитного приложения на multi-module с несколькими DFM — 2–4 недели в зависимости от сцепленности кода. Стоимость настройки одного модуля варьируется от $1500 до $3500, полная миграция — от $5000 до $15000. Внедрение окупается в среднем за 4 месяца (экономия ~$5000 в год для приложения с 50k установок).

Мы занимаемся Android-разработкой более 5 лет и реализовали 20+ проектов с DFM. Гарантируем корректную работу всех сценариев загрузки и отсутствие ошибок SplitCompat. Закажите настройку DFM у нас — получите консультацию инженера. Свяжитесь для аудита вашего проекта.