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

Ваш Android-застосунок може раптово впасти після ввімкнення мініфікації коду — це типова ситуація під час роботи з R8 та ProGuard. Ми налаштовуємо обфускацію та keep-правила так, щоб release-збірка працювала стабільно й без сюрпризів. Наша команда реалізує проєкт під ключ — від аналізу конфігурації до фінального тестування, з подальшою підтримкою.

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

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

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

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

Після включення 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-збірки.

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

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

  • Розробка мобільного додатка для компанії FEEDME
    Розробка мобільного додатка для компанії FEEDME
    1009
  • Розробка мобільного додатку для компанії XOOMER
    Розробка мобільного додатку для компанії XOOMER
    902
  • Розробка мобільного додатку для компанії RHL
    Розробка мобільного додатку для компанії RHL
    1331
  • Розробка мобільного додатку для компанії ZIPPY
    Розробка мобільного додатку для компанії ZIPPY
    1179
  • Розробка мобільного додатку для компанії Affhome
    Розробка мобільного додатку для компанії Affhome
    1106
  • Розробка мобільного додатку для компанії FLAVORS
    Розробка мобільного додатку для компанії FLAVORS
    713