Налаштування 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 (DFM) з on-demand доставкою. Тепер модуль завантажується лише тим, хто натиснув «Подивитися в AR». Розмір базового APK зменшився на 30%, що знизило вартість встановлення на $0.15 на користувача (економія $7500 при 50 000 встановлень). Конверсія у використання AR зросла на 15% завдяки відсутності зайвої ваги при встановленні. Dynamic Feature Modules (DFM) у 2–3 рази ефективніші за монолітну архітектуру за розміром APK. Наш клієнт додатково заощадив $10 000 на рік завдяки зменшенню витрат на трафік. Завдяки DFM ви заощаджуєте $10 000 на рік та зменшуєте APK на 60%.

Чому варто винести функції в Dynamic Feature Modules?

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

Як налаштувати 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 МБ 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 встановлень).

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