В чем разница между R8 и ProGuard
Что проверяют
Знаете ли вы, чем собирается релизная сборка сегодня. ProGuard в Android-сборке уже не используется по умолчанию, и ответ про «два похожих инструмента» выдаёт незнание текущего процесса.
Как отвечать
ProGuard это давний инструмент, который убирал неиспользуемый код, переименовывал классы и методы и делал часть оптимизаций, работая с байт-кодом JVM. R8 это его замена от Google, встроенная в Android Gradle Plugin начиная с версии 3.4 и включаемая одним флагом minifyEnabled true.
Ключевые отличия:
- место в конвейере: ProGuard был отдельным шагом перед превращением байт-кода в dex, R8 делает удаление лишнего, переименование, оптимизацию и компиляцию в dex за один проход. Отсюда заметно более быстрая сборка;
- качество оптимизаций: R8 агрессивнее встраивает методы, убирает недостижимые ветки, схлопывает классы и умеет удалять журналирование по правилам;
- правила: формат тот же, файлы
proguard-rules.proпродолжают работать, поэтому миграция обычно ничего не требует; - сжатие ресурсов остаётся отдельным флагом
shrinkResources, и безminifyEnabledоно не работает.
Обязательно скажите про практику: обфускация ломает всё, что опирается на имена классов и полей, то есть рефлексию, сериализацию через Gson или Moshi, Parcelable через рефлексию и имена в аннотациях. Такие места защищают правилами -keep, а карту переименований (mapping.txt) обязательно сохраняют и загружают в систему отчётов об ошибках, иначе стектрейсы из прода нечитаемы.
Где спотыкаются
Считают, что достаточно включить флаг и проверить, что приложение запускается. Ломаются обычно редкие экраны, и находит это уже пользователь.
Забывают про mapping.txt и потом не могут разобрать краш.
Пишут -keep class ** на весь пакет и сводят пользу от уменьшения размера к нулю.