Когда в Google Play Console вместо читаемого стек-трейса краша вы видите строки вида a.b.c.onCreate, причина почти всегда одна — приложение собрано с обфускацией R8/ProGuard, а файл деобфускации (mapping.txt) не был загружен в консоль. Без этого файла имена классов и методов в отчётах об ошибках остаются зашифрованными, и найти источник сбоя становится практически невозможно.
В этой статье разберём, что представляет собой файл деобфускации, где он создаётся при сборке, как загрузить его в Play Console и как вручную расшифровать стек-трейс, если автоматическая деобфускация недоступна.
Что такое файл деобфускации и зачем он нужен
При сборке релизной версии Android-приложения с включённым сжатием кода инструмент R8 (или устаревший ProGuard) переименовывает классы, методы и поля в короткие бессмысленные идентификаторы. Это уменьшает размер APK/AAB и затрудняет реверс-инжиниринг. Побочный эффект — краш-логи становятся нечитаемыми.
Чтобы решить эту проблему, R8 при каждой сборке генерирует mapping-файл — таблицу соответствий между исходными и обфусцированными именами. Именно этот файл и называют файлом деобфускации. По сути, это словарь, позволяющий «перевести» запутанный стек-трейс обратно в понятный вид с реальными именами методов и номерами строк.
Где находится mapping.txt после сборки
После успешной релизной сборки файл создаётся автоматически. Стандартный путь внутри проекта выглядит так:
app/build/outputs/mapping/release/mapping.txt
Если вы собираете другой вариант сборки (например, staging или конкретный flavor), имя папки release в пути заменяется на соответствующее название build type. Обратите внимание: файл перезаписывается при каждой новой сборке, поэтому его нужно сохранять отдельно для каждой опубликованной версии приложения.
⚠️ Внимание: mapping.txt уникален для каждой сборки. Файл от версии 1.2 не подойдёт для расшифровки крашей версии 1.3 — соответствия имён будут другими, и стек-трейс расшифруется неправильно.
- 📁 release — стандартная папка для релизной сборки;
- 🧩 flavor-сборки — у каждого flavor свой подкаталог внутри
outputs/mapping; - 🗄️ архивирование — храните mapping.txt вместе с тегом релиза в системе контроля версий или в CI-артефактах.
Как включить генерацию файла деобфускации
Генерация mapping-файла включается вместе с обфускацией в файле build.gradle уровня модуля. Минимальная конфигурация выглядит так:
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'),
'proguard-rules.pro'
}
}
}
Здесь minifyEnabled true активирует R8, и mapping-файл будет создан автоматически — отдельной опции для этого не требуется. Проверить факт генерации просто: соберите релизный AAB командой ./gradlew bundleRelease и убедитесь, что файл появился по указанному выше пути.
Загрузка файла в Google Play Console
Чтобы Play Console автоматически расшифровывала краши и ANR, mapping-файл нужно загрузить для каждой версии приложения. Порядок действий в общем виде такой:
- 🚀 Откройте раздел с отчётами о сбоях (раздел качества приложения) или страницу конкретной версии релиза;
- 📤 Найдите опцию загрузки файла деобфускации и выберите
mapping.txtот соответствующей сборки; - ✅ Дождитесь подтверждения — после этого новые краши будут отображаться в деобфусцированном виде.
Точное расположение кнопки загрузки может меняться с обновлениями интерфейса консоли, поэтому при затруднениях сверяйтесь с актуальной документацией Google Play Console. Важно понимать: загрузка файла не расшифровывает задним числом уже собранные отчёты — деобфускация применяется к новым поступающим крашам.
Ручная расшифровка стек-трейса
Если краш пришёл из стороннего источника (например, от пользователя по почте) или Play Console недоступна, стек-трейс можно расшифровать локально. Для этого в составе Android SDK и в инструментах R8/ProGuard есть утилита retrace (в старых версиях — proguardgui с аналогичной функцией).
java -jar retrace.jar mapping.txt stacktrace.txt
На вход утилита принимает файл деобфускации и текстовый файл с обфусцированным стек-трейсом, на выходе выдаёт читаемую версию с исходными именами классов, методов и номерами строк, если соответствующая отладочная информация была сохранена. Утилита обычно находится в каталоге инструментов командной строки SDK либо поставляется вместе с дистрибутивом R8.
☑️ Проверка перед публикацией релиза
Сравнение инструментов деобфускации
Разные инструменты работают с mapping-файлом по-разному. Сводная таблица поможет выбрать подходящий вариант:
| Инструмент | Назначение | Формат входных данных |
|---|---|---|
| Play Console | Автоматическая деобфускация крашей и ANR | Загруженный mapping.txt |
| retrace (R8) | Локальная расшифровка стек-трейсов | mapping.txt + текст стек-трейса |
| Firebase Crashlytics | Краш-репорты с деобфускацией | mapping.txt, загружаемый плагином Gradle |
| ProGuard GUI | Устаревший графический вариант retrace | mapping.txt + стек-трейс |
Для большинства проектов достаточно связки Play Console плюс локальный retrace на случай внешних логов. Если используется Crashlytics, mapping-файл обычно отправляется автоматически при сборке через соответствующий Gradle-плагин — проверьте это в настройках вашего проекта.
Типичные ошибки при работе с mapping-файлом
⚠️ Внимание: потеря mapping.txt для уже опубликованной версии практически необратима. Восстановить файл заново той же сборкой не получится — R8 при каждом запуске генерирует новые имена, даже если код не менялся.
Другая частая проблема — загрузка файла не от той версии. Внешне всё выглядит корректно, но стек-трейсы расшифровываются в бессмысленные сигнатуры, указывающие на несуществующие методы. Если вы видите подобное, первым делом проверьте соответствие версии файла и версии сборки.
Ещё один сценарий: разработчик отключает обфускацию «на всякий случай», чтобы не возиться с mapping-файлами. Это плохой компромисс — вы теряете и уменьшение размера приложения, и базовую защиту кода. Правильное решение — автоматизировать сохранение и загрузку файла деобфускации, а не отказываться от обфускации.
Что делать, если mapping.txt утерян
Полностью восстановить файл нельзя. Варианты действий: выпустить новую версию приложения с сохранённым mapping.txt и анализировать краши уже по ней; для критичного текущего краша попробовать сопоставить обфусцированные имена с кодом вручную по контексту стек-трейса — это трудоёмко и не всегда возможно.
FAQ: частые вопросы о файле деобфускации
Чем файл деобфускации отличается от файла нативных символов?
Mapping.txt расшифровывает Java/Kotlin-код, обфусцированный R8/ProGuard. Для нативных библиотек (C/C++) используется отдельный файл отладочных символов, который также загружается в Play Console. Это два разных механизма для разных частей приложения.
Можно ли восстановить mapping.txt, собрав проект заново?
Нет. Даже при неизменном коде R8 генерирует новые обфусцированные имена при каждой сборке, поэтому повторная сборка не воспроизведёт исходный файл. Файл нужно сохранять сразу после релизной сборки.
Опасно ли, если mapping.txt попадёт к третьим лицам?
Файл раскрывает соответствие обфусцированных имён исходным, что существенно упрощает реверс-инжиниринг приложения. Храните его как конфиденциальный артефакт — в закрытом репозитории или защищённом хранилище CI.
Нужен ли mapping.txt для debug-сборок?
Как правило, нет: в debug-сборках обфускация обычно отключена, и стек-трейсы читаемы сразу. Файл деобфускации актуален только для сборок с включённым minifyEnabled.
Расшифруются ли старые краши после загрузки файла в Play Console?
Загрузка mapping.txt применяется к вновь поступающим отчётам. Уже собранные обфусцированные краши можно расшифровать вручную через утилиту retrace, если у вас сохранился их текст.