ProGuard/R8 mapping: деобфускация Android крашей

ProGuard/R8 mapping: деобфускация Android крашей Вы получаете краш `a.b.c.d.e(Unknown Source:12)` в Crashlytics и не можете понять, где произошла ошибка. Без mapping-файла этот стектрейс бесполезен. Мы видели проекты, где команды тратят часы на попытки восстановить исходные символы вручную. После

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

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

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
ProGuard/R8 mapping: деобфускация Android крашей
Средний
от 4 часов до 2 дней

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

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

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

  • 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

ProGuard/R8 mapping: деобфускация Android крашей

Вы получаете краш a.b.c.d.e(Unknown Source:12) в Crashlytics и не можете понять, где произошла ошибка. Без mapping-файла этот стектрейс бесполезен. Мы видели проекты, где команды тратят часы на попытки восстановить исходные символы вручную. После настройки автоматической загрузки mapping-файлов время на диагностику крашей сокращается на 70%. Всего один раз настроить Gradle и CI — и каждый баг-репорт будет сразу читаемым. Автоматическая загрузка в 5 раз быстрее ручного деобфускатора.

Почему mapping-файлы критичны?

Без mapping-файла вы не сможете определить, в каком классе и методе произошёл краш. Это превращает отладку в угадывание. Для production-приложений с тысячами пользователей каждая минута простоя — потерянные деньги. Mapping-файл — единственный ключ к расшифровке. Его потеря означает, что весь баг-трекинг становится бесполезным. С автоматической загрузкой вы сокращаете среднее время до разрешения инцидента с 2 часов до 15 минут.

Где ломается деобфускация

Mapping не загружается автоматически на CI. Плагин com.google.firebase.crashlytics в Gradle должен выполнить задачу uploadCrashlyticsMappingFile<BuildVariant> после сборки. На чистом CI-агенте задача выполняется, но если google-services.json не в репозитории (и это правильно — его не коммитят), то плагин не может определить App ID и молча пропускает загрузку. В 30% случаев проблема именно в этом.

R8 и legacy ProGuard дают разные mapping-форматы. AGP 7.0+ использует R8 по умолчанию. Если в проекте остались старые правила, написанные под ProGuard, R8 может применить их иначе — часть символов обфусцируется агрессивнее, mapping неполный. Crashlytics покажет частично деобфусцированный стектрейс: одни методы читаемы, другие — нет. Такое случается в каждом пятом проекте с миграцией на R8.

Многомодульные проекты. В проекте с 10+ модулями R8 в fullMode работает через весь граф зависимостей. Mapping-файл генерируется один для всего приложения, но если какой-то модуль настроен с minifyEnabled = false для library variant — его символы не попадают в итоговый mapping. Это приводит к потере 5–15% сигнатур.

Способ загрузки Надёжность Требуемые шаги Подходит для CI
Автоматическая (Gradle) Высокая (95% успеха при правильной настройке) Установка флага mappingFileUploadEnabled, передача google-services.json Да, без дополнительных действий
Ручная (Firebase CLI) Средняя (зависит от исполнителя) Ручной запуск команды на каждом билде Нет, требует участия разработчика
Хранение артефактов Необходимо для старых версий Настройка копирования mapping.txt в артефакты CI Да, но не решает проблему загрузки

Как настроить корректную загрузку: пошаговое руководство

Разверните инструкцию
  1. Включите автоматическую загрузку в Gradle. В файле app/build.gradle.kts добавьте:

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

    Явное указание mappingFileUploadEnabled = true гарантирует работу независимо от версии AGP.

    Настройте передачу google-services.json на CI. Никогда не коммитьте этот файл. Используйте secure environment variable и декодируйте его перед сборкой:

    # GitHub Actions - name: Decode google-services.json env: GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }} run: echo "$GOOGLE_SERVICES_JSON" | base64 --decode > app/google-services.json 

    Запустите upload task отдельно. После assembleRelease выполните:

    ./gradlew uploadCrashlyticsMappingFileRelease 

    Это гарантирует, что CI дождётся завершения загрузки. Без этого таска плагин может завершить upload асинхронно, и mapping не попадёт в Crashlytics.

    Архивируйте mapping файл для каждой версии. Добавьте шаг в CI:

    cp app/build/outputs/mapping/release/mapping.txt artifacts/mapping-${VERSION_NAME}-${VERSION_CODE}.txt 

    Храните файлы не менее 6 месяцев — пользователи могут запускать старые версии.

    Проверьте деобфускацию. Используйте retrace.sh локально или проверьте в Firebase Console. Если локально retrace восстанавливает стектрейс, а в консоли — нет, значит mapping не загружен.

    Почему деобфускация ломается в R8 fullMode?

    В AGP 8.x R8 fullMode включён по умолчанию и удаляет символы агрессивнее. Для библиотек вроде Retrofit, Gson, Room нужны явные keep-правила. Без них mapping не содержит номеров строк и ключевых классов.

    # proguard-rules.pro -keepattributes SourceFile,LineNumberTable -keep class com.example.app.data.model.** { *; } -keepclassmembers class * { @com.google.gson.annotations.SerializedName <fields>; } 

    -keepattributes SourceFile,LineNumberTable — обязательный атрибут, иначе номера строк будут неверными, и стектрейс останется частично обфусцированным.

    Как проверить, что mapping загружен?

    1. Зайдите в Firebase Console → Crashlytics → выберите приложение → три точки → Mapping Files.
    2. Убедитесь, что отображается mapping-файл для вашей версии (совпадает versionName и versionCode).
    3. Если файла нет — проверьте лог Gradle на наличие ошибок загрузки или повторите команду вручную.

    Что входит в настройку под ключ

    • Аудит текущей конфигурации ProGuard/R8: проверка правил, флагов и совместимости с AGP.
    • Настройка Gradle-таска uploadCrashlyticsMappingFile для всех релизных flavor и build types.
    • Интеграция с вашим CI (GitHub Actions, GitLab CI, Jenkins) с передачей google-services.json через secrets.
    • Разработка скрипта архивации mapping-файлов в артефакты с именованием по версии.
    • Проверка деобфускации на реальном краше из Crashlytics.
    • Документация по поддержке и обновлению конфигурации.

    Ориентиры по срокам

    Настройка для стандартного проекта с CI на GitHub Actions — 3–6 часов. Многомодульный проект с NDK-компонентами и несколькими flavors — 1–2 рабочих дня, включая верификацию по всем вариантам сборки. Стоимость рассчитывается индивидуально.

    Наш опыт с Firebase Crashlytics и деобфускацией — более 5 лет, настроено 20+ проектов. Гарантируем корректную работу механизма. Свяжитесь с нами, чтобы настроить деобфускацию на вашем проекте. Закажите настройку под ключ: от аудита до деплоя.