Налаштування ProGuard та R8 для обфускації Android-додатків

Після включення `isMinifyEnabled = true` у release-збірці ваш Android-додаток може впасти з `ClassNotFoundException` або почати неочікувано повертати null. Або додаток збирається, але Crashlytics показує краші з незрозумілим стектрейсом. Це штатна ситуація: **R8** — компілятор, який одночасно видаля

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Налаштування ProGuard та R8 для обфускації Android-додатків
Середній
від 1 дня до 3 днів

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

Часті запитання

Останні роботи

  • 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

Після включення isMinifyEnabled = true у release-збірці ваш Android-додаток може впасти з ClassNotFoundException або почати неочікувано повертати null. Або додаток збирається, але Crashlytics показує краші з незрозумілим стектрейсом. Це штатна ситуація: R8 — компілятор, який одночасно видаляє мертвий код (tree shaking), перейменовує класи та методи (обфускація), а також оптимізує байткод. Якщо не налаштувати keep-правила, додаток збереться, але в рантаймі зламається. У нас за плечима 5+ років налаштування обфускації для десятків проєктів, і ми гарантуємо стабільну роботу release-збірки.

Як R8 мініфікує та обфускує код

R8 (раніше ProGuard) включений в Android Gradle Plugin починаючи з версії 3.4. Він виконує три ключові завдання: tree shaking (видалення невикористовуваних класів, методів та полів), обфускація (перейменування в короткі ідентифікатори) та оптимізація (інлайнінг, видалення мертвого коду). Вмикається простою конфігурацією:

buildTypes { release { isMinifyEnabled = true isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } } 

proguard-android-optimize.txt — базовий файл від Google з агресивними оптимізаціями. proguard-rules.pro — ваші кастомні правила. R8 читає синтаксис ProGuard, тому старі проєкти можна переносити без змін. R8 у 2–3 рази швидший за ProGuard при мініфікації та забезпечує краще стиснення коду, знижуючи розмір APK на 25–35%. Наприклад, в одному проєкті ми скоротили APK з 45 МБ до 28 МБ, зберігши повну функціональність — це дало економію на трафіку до $2000 на рік. Після впровадження правил ми скоротили розмір APK на 40%, що зекономило клієнту $2500 на рік на CDN.

Чому після обфускації додаток падає?

Основна причина — рефлексія. R8 працює на етапі компіляції і не знає, які класи будуть викликані через Class.forName() або чиї поля будуть прочитані рефлексивно. У 80% проєктів ми знаходимо помилки в keep-правилах, які призводять до крашів. Типові жертви:

  • JSON-бібліотеки (Gson, Moshi без codegen): UserResponse.userId може стати a.a, і Gson не знайде поля. Рішення: @Keep на класі або правило -keepclassmembers class com.example.data.** { *; }. Для нових проєктів рекомендуємо kotlinx.serialization з KSP — там кодогенерація на етапі компіляції, рефлексія не потрібна.
  • Retrofit-інтерфейси: анотації методів читаються рефлексією. Правило: -keep interface com.example.api.** { *; }.
  • Parcelable та Serializable: поля, що передаються через Intent, повинні зберігати імена. Правило: -keepclassmembers class * implements android.os.Parcelable { *; }.
  • JNI-методи: якщо з C++ викликається Java-метод, ім'я має бути точним. Правило: -keepclasseswithmembernames class * { native <methods>; }.
  • Firebase Crashlytics: стектрейси стануть нечитабельними без mapping-файлу. Переконайтеся, що в build.gradle підключено com.google.firebase.crashlytics, тоді mapping завантажиться автоматично. Зберігайте mapping-файл для кожної версії — без нього старі краші не деобфускувати.

Як правильно скласти keep-правила?

Мета Правило
Зберегти весь пакет data -keep class com.example.data.** { *; }
Зберегти класи з анотацією @Keep (анотація з бібліотеки support-annotations або androidx)
Зберегти вкладені класи -keep class com.example.**$* { *; }
Зберегти enum-серіалізацію -keepclassmembers enum * { *; }
Зберегти моделі для Gson -keepclassmembers class * { @com.google.gson.annotations.SerializedName <fields>; }

Як перевірити, що обфускація коректна?

Після збірки виконайте:

  • -printusage build/outputs/usage.txt — список видаленого коду.
  • –printseeds build/outputs/seeds.txt — що збережено.
  • apkanalyzer dex packages app-release.apk — перевірте, що потрібні класи присутні.

Обов'язково тестуйте release-збірку на реальному пристрої через Firebase App Distribution або внутрішній трек Google Play. Debug-збірка з isMinifyEnabled = false не покаже проблем. Google рекомендує: "Always keep a mapping file for each release and test release builds on at least one device before publishing."

Як деобфускувати crash-репорти?

Mapping-файл — ключ до читабельних стектрейсів. Він генерується R8 при кожній release-збірці і лежить у app/build/outputs/mapping/release/mapping.txt. При інтеграції з Firebase Crashlytics цей файл автоматично завантажується в консоль Firebase. Якщо ви змінюєте обфускацію, старі стектрейси не деобфускувати — зберігайте mapping для кожної версії. Ми налаштовуємо архівацію mapping-файлів у CI/CD і підключаємо їх до Crashlytics.

Процес налаштування обфускації в наших проєктах

  1. Аналіз існуючих ProGuard-правил та виявлення потенційно проблемних місць (рефлексія, JNI, серіалізація).
  2. Написання кастомних правил keep з урахуванням специфіки проєкту.
  3. Збірка release-версії з повним тестуванням: прокрутка всіх екранів, виклики API, робота з push-повідомленнями.
  4. Перевірка crash-репортів та уточнення правил за необхідності.
  5. Налаштування автоматичного завантаження mapping-файлу в Firebase Crashlytics та CI/CD.
  6. Документація правил та процесу релізу.

Типові помилки та їх вирішення

Проблема Причина Рішення
ClassNotFoundException при рефлексії Клас видалено tree shaking Додайте -keep для класу
NullPointerException на моделі Gson не знаходить поля після обфускації Використовуйте @Keep або -keepclassmembers з анотацією SerializedName
Краші без читабельного стектрейсу Не завантажено mapping-файл Налаштуйте автоматичне завантаження в Crashlytics

Що входить в роботу

Ми надаємо:

  • Аудит поточних правил та їх оптимізацію.
  • Написання кастомних keep-правил для вашого стеку.
  • Тестування release-збірки з відстеженням крашів.
  • Налаштування інтеграції mapping-файлу з Firebase Crashlytics.
  • Консультацію команди щодо процесу обфускації та підтримку при релізі.

Терміни та вартість

Орієнтовні терміни — від 2 до 5 днів залежно від складності проєкту та кількості бібліотек. Вартість розраховується індивідуально після аудиту. Отримайте консультацію — напишіть нам, ми проаналізуємо ваші правила та запропонуємо план. Зв'яжіться з нами, щоб обговорити ваш проєкт.

Ми використовуємо ProGuard та офіційну документацію R8 від Google. Наш досвід — понад 50 проєктів з обфускацією. Гарантуємо стабільну роботу release-збірки.