Освой программирование играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

ProGuard

ProGuard - утилита, которая удаляет из готового кода неиспользуемые фрагменты и изменяет имена переменных и методов для усложнения реверс-инжиниринга приложения. Также позволяет уменьшить размер загружаемых на устройство файлов.

Во время своей работы утилита совершает несколько последовательных шагов.

На первом шаге Proguard рекурсивно определяет, какие классы и члены классов (переменные, методы, константы) используются. Все другие классы или члены классов будут удалены из приложения.

Следующий шаг - оптимизация. Proguard может поменять модификаторы классов и методов, удалить неиспользуемые параметры и т.д. Не всегда подобная оптимизация идёт на пользу, поэтому часто этот шаг пропускают.

Важная часть - обфускация. ProGuard переименовывает классы и члены классов, которые не являются точками входа. Точки входа сохраняют свое оригинальное название. Это затрудняет декомпиляцию и исследование работы приложения (reverse engineering).

В Android не используется, но для обычных приложений Java также используется дополнительный шаг - проверка, что код не может случайно или намеренно вырваться из песочницы виртуальной машины Java. Для того, чтобы эта проверка проходила быстрее, компилятор добавляет к файлам классов дополнительную информацию. Соответственно, ProGuard должен в конце своей работы сформировать новую информацию для этой проверки.

В приложении под Android пользовательский интерфейс чаще всего описывается с помощью XML. Часть классов, использующихся при описании интерфейса, нигде в коде не используется. Поэтому, если не сообщить об этих классах ProGuard, они будут удалены. XML с описаниями интерфейса в процессе сборки анализируются аналогично AndroidManifest.xml, и все перечисленные там классы добавляются в файл конфигурации для ProGuard.

Сформированный файл сохраняется в в app/build/intermediates/proguard-rules/debug/aapt_rules.txt.

Второй файл конфигурации Proguard, который по умолчанию используется при сборке приложения под Android, приходит в составе SDK. Этот файл явно указан в build.gradle нашего приложения.


buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

proguard-android.txt — это дефолтный файл конфигурации, поставляемый с SDK. Экспериментаторы могут заменить его на proguard-android-optimize.txt.

proguard-rules.pro — файл, в который предлагается писать свои директивы для ProGuard. Изначально пустой, находится в каталоге приложения.

Вы можете включить ProGuard не только для release, но и для debug версий. Это очень полезно, потому что поведение приложения с включенным ProGuard может отличаться от приложения с выключенным ProGuard совершенно неожиданным образом. Чем раньше все эти неожиданности будут обнаружены и исправлены, тем лучше. За включение ProGuard отвечает директива minifyEnabled.


minifyEnabled true

Если нет уверенности в правильности работы ProGuard, имеет смысл выключить обфускацию. Для этого добавьте в proguard-rules.pro следующую директиву:


-dontobfuscate

Конфигурации для всех сторонних библиотек, которые вы взяли в android-proguard-snippets, храните в каталоге proguard внутри каталога вашего приложения. Тогда подключить сразу весь каталог можно с помощью следующей директивы в build.gradle:


proguardFiles fileTree('proguard').asList().toArray()

Очень часто возникают проблемы с ProGuard при подключении сторонних библиотек. Обычно, авторы библиотек прикладывает к описанию необходимые комментарии для решения проблемы.

Использованные материалы

ProGuard. Часть 1. 95% граблей

Реклама