- Набор средств внешнего набора правил
- Средство «RuleSet»
- Действие «PolicyFromService».
- Служба «RuleSet»
- Запуск средства
- Как перестать бояться Proguard и начать жить
- О чем это
- Code shrinking
- Optimisation
- Obfuscation
- Принцип работы
- Сопутствующие файлы
- Как дела обстоят в Android
- Конфиги
- Keep rules
- Optimisation tuning
- Прочие полезные опции
- Практика
- Определиться с начальными входными точками
- Проверить все библиотеки
- Провести инспекцию своего кода
- Тесты
- APK Analyzer
- Для авторов библиотек
- R8, DexGuard и Redex
- Вместо заключения
Набор средств внешнего набора правил
Обычно, когда правила используются в приложении рабочего процесса, они являются частью сборки. В некоторых случаях, возможно, потребуется создать наборы правил отдельно от сборки, чтобы можно было обновлять их, без повторного построения и развертывания сборки рабочего процесса. В этом образце показано, как управлять и изменять наборы правил в базе данных, а также как получить доступ к этим наборам правил из рабочего процесса в среде выполнения. Это позволяет запускать экземпляры рабочего процесса, чтобы автоматически включать изменения в наборах правил.
пример внешнего набора правил набор средств содержит средство на основе Windows Forms, которое можно использовать для управления и редактирования версий набора правил в базе данных. Также включены действие и служба размещения для выполнения этих правил.
для этого примера требуется Microsoft SQL Server.
Visual Studio предоставляет редактор набора правил в составе Windows Workflow Foundation (WF). Редактор запускается двойным щелчком действия Policy в рабочем процессе; редактор выполняет сериализацию объекта набора правил в файл с расширением RULES, связанный с рабочим процессом (действие Policy запускает экземпляр набора правил из рабочего процесса). При построении проекта рабочего процесса выполняет компиляция в сборку файла с расширением RULES как ресурса.
Компоненты данного образца включают следующее:
Средство пользовательского графического интерфейса набора правил, которое используется для редактирования и управления версиями набора правил в базе данных.
Служба набора правил, настройка которой выполняется в ведущем приложении, осуществляет доступ к наборам правил из базы данных.
Действие ExternalPolicy запрашивает набор правил из службы набора правил и запускает набор правил из рабочего процесса.
Взаимодействие компонентов показано на следующем рисунке. В следующих разделах приведено описание каждого из компонентов.
Средство «RuleSet»
На следующем рисунке показан снимок экрана средства создания правил. В меню хранилище правил можно загрузить доступные наборы правил из базы данных и сохранить измененные наборы правил обратно в хранилище. Файл конфигурации приложения предоставляет строку подключения базы данных для базы данных набора правил. При запуске это средство автоматически загружает наборы правил из настроенной базы данных.
Средство «RuleSet» служит для применения основного и вспомогательного номеров версий к наборам правил, что позволяет одновременно создавать и хранить несколько версий (средство не предоставляет возможности блокировки или другие возможности управления конфигурацией, помимо поддержки версий). С помощью данного средства можно создавать новые версии набора правил или удалять существующие версии. При нажатии кнопки создать средство создает новое имя набора правил и применяет версию 1,0. При копировании версии средство создает копию выбранной версии набора правил, включая содержащиеся правила, и присваивает новые уникальные номера версий. Эти номера версий основаны на номерах версий существующих наборов правил. Имя и номера версий набора правил можно изменить с помощью связанных полей на форме.
При нажатии кнопки изменить правила запускается редактор набора правил, как показано на следующем рисунке:
это повторное размещение диалогового окна редактора, которое является частью надстройки Windows Workflow Foundation Visual Studio. Оно предоставляет тот же набор функциональных возможностей, включая поддержку Intellisense. Правила создаются для целевого типа (например, рабочего процесса), связанного с набором правил в средстве. Если нажать кнопку Обзор в главном диалоговом окне средства, откроется диалоговое окно выбора рабочего процесса или типа , как показано на рис. 4.
Рисунок 4. Выбор рабочего процесса или типа
Диалоговое окно выбора рабочего процесса или типа можно использовать, чтобы указать сборку и конкретный тип в этой сборке. Этот тип является конечным типом, по которому создаются (и запускаются) правила. В большинстве случаев конечным типом является рабочий процесс или какой-либо другой тип действия. Тем не менее можно запустить набор правил по любому типу .NET.
Путь к файлу сборки и набору правил типа name are stored with the в базе данных, чтобы при извлечении набора правил из базы данных средство предпримет попытку автоматически загрузить целевой тип.
При нажатии кнопки ОК в диалоговом окне выбора рабочего процесса или типа он проверяет выбранный тип на соответствие с набором правил, чтобы убедиться, что целевой тип содержит все элементы, на которые имеются ссылки в правилах. Ошибки отображаются в диалоговом окне ошибок проверки . Можно выбрать продолжение изменения, несмотря на ошибки, или нажмите кнопку Отмена. В меню Сервис диалогового окна основное средство можно нажать кнопку проверить , чтобы повторно проверить версию набора правил на соответствие целевому действию.
В меню данные в средстве можно импортировать и экспортировать наборы правил. При нажатии кнопки Импорт появляется диалоговое окно выбора файла, в котором можно выбрать файл rules. Это может быть файл, изначально созданный в Visual Studio. В RULES-файле должен содержаться сериализованный экземпляр RuleDefinitions с коллекцией условий и коллекцией наборов правил. средство не использует коллекцию условий, но использует RuleDefinitions формат. rules, чтобы разрешить взаимодействие с Visual Studioной средой.
После выбора файла rules открывается диалоговое окно выбора набора правил . Можно использовать диалоговое окно для выбора наборов правил из файла, который требуется импортировать (по умолчанию указаны все наборы правил). Наборы правил в RULES-файле не содержат номеров версии, поскольку их версии в рамках проекта WF совпадают с версией сборки. Во время процесса импорта средство автоматически назначает следующий доступный основной номер версии (который можно изменить после импорта); Номера назначенных версий можно просмотреть в списке выбора набора правил .
Для каждого импортируемого набора правил средство пытается поместить связанный тип из папки bin\Debug в местоположение RULES-файла (если есть), в зависимости от членов, используемых в наборе правил. Если средство обнаруживает несколько соответствующих типов, оно пытается выбирать тип в соответствии с совпадением между именем RULES-файла и именем типа (например, тип Workflow1 соответствует файлу «Workflow1.rules»). При наличии нескольких совпадений предлагается выбрать тип. Если механизму автоматической идентификации не удается найти соответствующую сборку или тип, после импорта можно нажать кнопку Обзор в главном диалоговом окне, чтобы перейти к связанному типу. На следующем рисунке показан селектор набора правил.
При нажатии кнопки Экспорт данных в главном меню средства диалоговое окно выбора набора правил появляется снова, из которого можно определить наборы правил из базы данных, которую необходимо экспортировать. При нажатии кнопки ОК появляется диалоговое окно Save File (сохранить файл ), в котором можно указать имя и расположение результирующего файла rules. Поскольку в RULES-файл не содержатся сведения о версии, для заданного имени набора правил можно выбрать только одну версию набора правил.
Действие «PolicyFromService».
Код для действия PolicyFromService является прямолинейным. Функционирование этого кода во многом аналогично действию Policy , предоставляемому в WF, однако вместо извлечения конечного набора правил из RULES-файла данный код выполняет вызов службы размещения, чтобы получить экземпляр набора правил. Затем код запускает набор правил из экземпляра действия корневого рабочего процесса.
Чтобы использовать данное действие в рабочем процессе, следует добавить ссылку на сборки PolicyActivities и RuleSetService из проекта рабочего процесса. Обсуждение способов добавления действия на панель инструментов см. в процедуре в конце данного раздела.
После того, как действие помещено в рабочий процесс, необходимо указать имя набора правил, который требуется запустить. Можно ввести имя как буквенное значение, либо выполнить привязку к переменной рабочего процесса или свойству другого действия. Дополнительно можно задать номера версий для конкретного набора правил, который требуется запустить. Если оставить значение по умолчанию «0» для основного и вспомогательного номеров версий, действию будет автоматически присвоен номер последней версии в базе данных.
Служба «RuleSet»
Эта служба отвечает за извлечение заданной версии набора правил из базы данных и ее возврат в вызывающее действие. Как уже обсуждалось ранее, если значения основной и вспомогательной версии, переданные в вызов GetRuleSet оба равны «0», служба выполняет извлечение последней версии. На этой стадии не выполняется кэширование определений или экземпляров набора правил; также, отсутствуют функции пометки версий набора правил как «развертываемых», чтобы отличить их от наборов правил в процессе выполнения.
База данных, доступ к которой осуществляется службой, должна быть настроена на узле с помощью файла конфигурации приложения.
Запуск средства
В папке, в которой задана таблица набора правил, используемая средством и службой, также содержится файл «Setup.sql». Можно запустить пакетный файл «Setup.cmd», чтобы создать базу данных правил в SQL Express и задать таблицу набора правил.
При редактировании пакетного файла или файла «Setup.sql», если использование SQL Express или размещение таблицы в базе данных с именем, отличным от Rules , не задано, файлы конфигурации приложения в средстве «RuleSet» и проекты UsageSample следует редактировать, используя одинаковые сведения.
После запуска скрипта «Setup.sql» можно построить решение ExternalRuleSetToolkit , а затем запустить средство «RuleSet» из проекта «ExternalRuleSetTool».
Решение консольного приложения последовательного рабочего процесса RuleSetToolkitUsageSample включает образец рабочего процесса. Рабочий процесс включает действие PolicyFromService и две переменные: orderValue и discount , для которых выполняется запуск конечного набора правил.
Чтобы использовать этот образец, необходимо построить решение RuleSetToolkitUsageSample . Затем в главном меню средства набора правил щелкните Импорт данных и укажите файл дискаунтрулесет. rules в папке рулесеттулкитусажесампле. Щелкните пункт меню хранилище правил — сохранить , чтобы сохранить импортированный набор правил в базе данных.
Поскольку ссылка на сборку PolicyActivities дана из образца проекта рабочего процесса, действие PolicyFromService используется в рабочем процессе. Тем не менее, это оно не отображается на панели инструментов по умолчанию. Чтобы добавить действие на панель инструментов, необходимо сделать следующее.
Щелкните правой кнопкой мыши панель элементов и выберите пункт Выбрать элементы (это может занять некоторое время).
Когда откроется диалоговое окно Выбор элементов панели элементов , перейдите на вкладку действия .
Перейдите к PolicyActivities сборке в ExternalRuleSetToolkit решении и нажмите кнопку Открыть.
Убедитесь, что PolicyFromService действие выбрано в диалоговом окне Выбор элементов панели элементов , и нажмите кнопку ОК.
Теперь действие должно отобразиться в области элементов в категории компоненты рулесеттулкитусажесампле .
Служба «RuleSet» уже настроена на узле консольного приложения с помощью приведенного ниже оператора в файле «Program.cs».
Можно также настроить службу на узле с помощью файла конфигурации. Дополнительные сведения см. в документации по пакету SDK.
Файл конфигурации приложения добавляется в проект рабочего процесса, чтобы указать строку подключения для базы данных, которая будет использоваться службой. Средством «RuleSet» должна использоваться та же строка подключения, что указывает на базу данных, содержащую таблицу набора правил.
Теперь можно выполнить проект RuleSetToolkitUsageSample , а также остальные консольные приложения рабочего процесса. нажмите клавишу F5 или Ctrl + F5 в Visual Studio или непосредственно запустите RuleSetToolkitUsageSample.exe файл.
Чтобы повторную скомпилировать выборку использования, необходимо закрыть средство «RuleSet», поскольку средство загружает сборку выборки использования.
Источник
Как перестать бояться Proguard и начать жить
Здравствуйте, я Android разработчик и я больше не боюсь ProGuard.
Обычно, об этой утилите вспоминают, когда сталкиваются с dalvik dex-limit issue или с требованием улучшить безопасность приложения. К сожалению, правильно настроить Proguard удается далеко не с первого раза. Я часто наблюдал, как многие, сломав проект, выключают Proguard и включают поддержку Mulditex и каждый раз немножечко грустил по этому поводу, ведь Proguard помогает как сократить размер приложения, так и повысить его производительность.
В итоге, я решил написать статью, в которую смогу поместить всю полезную информацию, которую я узнал за несколько лет работы с Proguard и которая могла бы помочь как совсем новичкам, так и тем, кто уже что-то знает.
О чем это
Proguard — это open-source утилита для оптимизации и обфускации Java кода. Этот инструмент обрабатывает уже скомпилированный Java код, так что он должен работать с любым JVM языком. Точнее сказать, сам язык для Proguard безразличен, важен только байткод. Все манипуляции Proguard-а с байткодом можно разделить на 3 основных категории: Code shrinking, Optimisation и Obfuscation.
Code shrinking
Да, довольно странная затея писать код, а потом его удалять, но это реальность Android-разработки. Речь, конечно, не о собственноручно написанном коде (хотя и такое бывает), а о тоннах мертвого груза, который приносят библиотеки всех сортов. Guava, Apache Commons, Google Play Services и другие ребята могут раздуть размер apk файла с 500кб до пары десятков мегабайт. Порой это заходит так далеко, что программа не может скомпилироваться из-за превышения Dalvik methods limit. Proguard поможет удалить весь неиспользуемый код и сократить размер приложения обратно до нескольких мегабайт.
Optimisation
Помимо удаления ненужного кода, Proguard может оптимизировать код оставшийся. В его арсенале имеется control flow analysis, data-flow analysis, partial evaluation, static single assignment, global value numbering, liveness analysis. Proguard умеет выполнять peephole-оптимизации, уменьшать количество аллокаций переменных, упрощать хвостовые рекурсии и многое другое (wiki). Помимо таких общих операций, у Proguard есть оптимизации, полезные именно для Android-платформы, например, замена enum классов int-ами, удаление логгирующих инструкций.
Obfuscation
Напоследок, Proguard может превратить весь ваш код в нечитабельное месиво переименовав все классы, методы и поля в наборы случайных (на самом деле не совсем случайных) букв. Это очень полезная опция, так как декомпилировать ваш apk-файл может любой желающий, а разбираться в обфусцированном коде хватит терпения не у каждого.
Принцип работы
Proguard работает в 3 шага в той последовательности, которая была описана выше: code shrinking → optimization → obfuscation. Каждый из шагов опциональный.
Шаг Optimization в случае Android SDK по умолчанию выключен.
Для работы Proguard нужно предоставить 3 компонента:
- Ваш скомпилированный код — архив с class -файлами вашей программы и всех библиотек, которые вы используете (jar, aar, apk, war, zip и т.п.). Proguard модифицирует только уже скомпилированный код и не имеет никакого отношения к исходному.
- Конфигурационный файл(ы) — файл(ы), содержащие все правила, опции и настройки, с которыми вы хотите запустить обработку.
- Library jars (aar, apks, . ) — классы платформы, на которой работает ваша программа. В случае с Android это android.jar . Эти архивы нужны только для правильного анализа вашего кода, они не будут модифицированы (в этом нет смысла, т.к. android.jar находится «в телефоне», у нас нет к нему доступа).
(Картинка из презентации Jeb Ware, ссылка в конце статьи)
Используя library classes и ваши конфиг-файлы Proguard определяет все точки входа в вашу программу (seeds). Другими словами, определяет те классы и методы, которые могут быть вызваны извне и которые трогать нельзя. Затем, начиная с обнаруженных seeds, Proguard рекурсивно обходит весь ваш код, помечая флажком «используемо» все, до чего смог дотянуться. Весь остальной код будет удален. В конфиге требуется указать хотя бы одну точку входа. Для стандартной java-программы это функция main . В Android нет единой точки входа в программу, вместо этого у нас есть стандартные компоненты (Activity, Service и т.п.), которые создаются и вызываются системой. К счастью, нам здесь ничего самостоятельно указывать не надо, Android SDK создаст нужный конфиг за нас.
Сопутствующие файлы
После обнаружения всех входных точек Proguard запишет их в файл seeds.txt .
Весь тот код, который Proguard посчитал ненужным, записывается в файл usage.txt . Это довольно странное название для файла, содержащего удаленный код, было бы правильнее назвать его unusage.txt, но мы имеем то, что имеем, просто помните об этом.
На шаге обфускации будет создан файл mapping.txt , содержащий пары -> . Этот файл пригодится тогда, когда потребуется деобфусцировать программу, например, прочитать stacktrace. Вручную маппить файлы обратно не требуется, в Android SDK есть утилиты retrace и proguardui , которые помогут. Более того, если вы используете Fabric Crashlytics, то их gradle plugin умеет самостоятельно находить и загружать этот файл в консоль, так что вам не надо беспокоится об этом.
В случае с Android, эти файлы обычно находятся в app/build/output/mapping/
Еще Proguard создает файл dump.txt , который содержит все то, что Proguard положил в итоговый архив. Мне он никогда не пригождался, но, возможно, кому-то он будет полезен.
Как дела обстоят в Android
Android Gradle Plugin умеет запускать Proguard самостоятельно. Все, что вам нужно сделать, это включить эту опцию и указать конфиг-файлы.
minifyEnabled true — включаем Proguard на этапе сборки
proguardFiles — список конфиг-файлов. Правила из всех конфиг-файлов будут добавлены в общий список в порядке их появления.
proguard-rules.pro — это наш конфиг-файл со специфичными для конкретного проекта правилами
getDefaultProguardFile(‘proguard-android.txt’) — функция, возвращающая стандартный конфиг-файл для Android-приложений. Он лежит в AndroidSDK/tools/proguard
На самом деле, в Android SDK есть два конфига: proguard-android.txt и proguard-android-optimize.txt . В первом из них есть опция -dontoptimize , которая выключает все оптимизации. Если хотите включить оптимизацию — используйте второй конфиг.
Помимо этих стандартных конфигов Android SDK (aapt) автоматически генерирует набор правил для ресурсов: aapt проверяет все xml файлы (включая манифест), чтобы найти все активити, сервисы, вьюшки и т.п. и сгенерировать для них нужные правила. Сгенерированные правила можно найти в app/build/intermediates/proguard-rules/ /aapt_rules.txt . Вам не нужно его указывать самостоятельно, Android Gradle Plugin добавит эти правила автоматически.
(Картинка из презентации Jeb Ware, ссылка в конце статьи)
Конфиги
Настройка Proguard это самая основная часть работы с ним и в то же время самая сложная. Неправильный конфиг может легко сломать компиляцию приложения и само приложение в рантайме. Все доступные опции конфигурации подробно документированы на офф. сайте.
Среди всех опций я бы выделил 3 наиболее важных группы:
- keep rules — Все возможные точки входа в программу. Правила говорящие Proguard-у, какие классы или части классов нужно сохранить без изменения или какие из модификаций допустимы для конкретных классов.
- optimisation tuning — указывают какие оптимизации допустимы, сколько циклов оптимизации нужно сделать.
- работа с предупреждениями, ошибками и debugging
Keep rules
Это набор опций, предназначенных для того, чтобы защитить ваш код от беспощадного Proguard. В самом общем виде такое правило выглядит так:
keep — самая общая из таких опций (есть и другие), говорящая Proguard сохранить сам класс и все его составляющие(class members): поля и методы.
class_specification — шаблон, указывающий на класс(ы) или его части (class members). Общий вид шаблона очень большой, его можно посмотреть в офф. документации. Можно к нему обращаться, однако в целом, можно просто помнить, что у нас есть возможность составить шаблон из таких составляющих:
- выбрать все классы с определенным именем, пакетом
- выбрать все классы, наследующие/реализующие определенные классы/интерфейсы
- выбрать все классы с определенными модификаторами и/или определенными аннотациями
- выбрать все методы с определенным именем, модификаторами, аргументами и возвращаемым значением
- выбрать все поля определенным именем, модификаторами, определенного типа.
есть возможность использовать wildcards
Еще раз, это не строгое описание шаблона, это скорее список возможностей, которые у нас есть. А вот несколько примеров:
-keep public class com.example.MyActivity
сохранить класс com.example.MyActivity
-keep public class * extends android.app.Activity
сохранить все публичные классы, наследующие android.app.Activity
найти все публичные классы, наследующие android.view.View и сохранить в них 3 конструктора с определенными параметрами + все публичные методы, с модификатором void , любыми аргументами и именем, начинающимся на set . Все остальные части класса могут быть модифицированы.
-keep class com.habr.** < *; >
сохранить все классы и все их содержимое в пакете com.habr
modifiers — дополнение к keep-правилу:
- includedescriptorclasses — помимо указанного класса/метода/поля нужно сохранить все классы, встречающиеся в их дескрипторах.
- includecode — содержимое метода, на который указывает это конкретное правило, тоже трогать нельзя.
- allowshrinking — классы, на которые указывает это правило, не являются входными точками (seeds) и их можно удалять, но только если они не используются в самой программе. Однако, если после codeshrinking этот код остался (по причине того, что его кто-то использует), оптимизировать/обфусцировать этот код нельзя.
- allowoptimization — классы, на которые указывает это правило, можно только оптимизировать, но нельзя удалять или обфусцировать.
- allowobfuscation — классы, на которые указывает это правило, можно только обфусцировать, но нельзя удалять или оптимизировать.
Помимо keep , есть еще несколько опций:
-keepclassmembers — указывает, что нужно сохранить class members, если сам класс сохранился после code shrinking.
-keepclasseswithmembers — указывает, что нужно сохранит классы, содержимое которых попадает под указанный шаблон. Например, -keepclasseswithmembers class * < public (android.content.Context); >— сохранит все классы, у которых есть публичный конструктор с одним аргументом типа Context .
-keepnames — сокращение для -keep,allowshrinking .
-keepclassmembernames — сокращение для -keepclassmembers,allowshrinking .
keepclasseswithmembernames — сокращение для -keepclasseswithmembers,allowshrinking .
Optimisation tuning
Самой главной опцией здесь является флаг -dontoptimize . Если он присутствует, ни одна оптимизация не будет выполнена и все остальные опции оптимизации будут проигнорированны.
Опций оптимизаций много, но самыми полезными мне кажутся следующие:
-optimizations optimization_filter — перечисление всех способов, которые вы хотите использовать. Лучше использовать тот набор, который указан в proguard-android-optimize.txt или его подмножество. Список всех оптимизаций можно найти тут.
-optimizationpasses n — количество циклов оптимизации. Несколько циклов могут улучшить результат. При этом Proguard достаточно умный, чтобы прекратить циклы, если увидит, что результат не улучшился с прошлого раза.
-assumenosideeffects class_specification — указывает, что данный метод не имеет сайд-эффектов и только возвращает какое-то значение. Proguard удалит вызовы этого метода, если обнаружит, что возвращаемый им результат не используется. Пожалуй, самое распространенное применение этой опции — удаление всех отладочных логов: -assumenosideeffects class android.util.Log
-allowaccessmodification — показать все, что скрыто 🙂 Отличная опция, позволяющая избаиться от кучи искусственных accessor-методов для вложенных классов. Работает только в паре с -repackageclasses
-repackageclasses — разрешает переместить все классы в один указанный пакет. Это больше относится к обфускации, но в то же время, дает хорошие результаты в оптимизации.
Прочие полезные опции
-dontwarn и -dontnote
Proguard очень умный и всегда сообщает о подозрительных местах во время анализа кода, иногда это заметки, иногда — предупреждения. Если ваш билд не собирается при включенном Proguard, обязательно прочитайте все производимые им логи, он обязательно напишет, что пошло не так и, скорее всего, даже подскажет как это исправить. Прочитав все сообщения, вы или исправляете проблему, или игнорируете сообщение одной из этих опций, если уверены, что проблемы нет.
Например, бывает, что какая-то java-бибилиотека использует platform-классы, которых нет в android.jar и Proguard предупредит об этом. Если вы уверены, что эта библиотека работает нормально в Android-окружении, вы можете отключить это предупреждение -dontwarn java.lang.management.**
-whyareyoukeeping class_specification — полезная опция, которая напечатает причину, по которой Proguard решил не трогать этот класс/метод.
-verbose — печатать более подробные логи и исключения
-printconfiguration — напечатать полный список опций из всех конфиг-файлов, которые были использованны, включая правила из библиотек и сгенерированные через aapt.
-keepattributes SourceFile, LineNumberTable — сохраняет мета-информацию (имена файлов, нумерацию строк), что бы иметь возможность отлаживать код в IDE и получать осмысленный stacktrace. Обязательно добавляйте эту опцию.
Практика
Обычно бывает так: включаешь Proguard и он ломает тебе весь проект выдавая тонну ошибок. Многие на этом шаге выключают Proguard и стараются к нему не возвращаться. Я попробую дать несколько советов, что бы этот процесс перехода был попроще.
Определиться с начальными входными точками
Если вы Android-разработчик, тут все предельно элементарно — просто выберите один из двух стандартных конфигов из Android SDK: proguard-android.txt или proguard-android-optimize.txt , они позаботятся о всем, что должно остаться нетронутым.
Проверить все библиотеки
В последнее время все больше и больше библиотек распространяются уже с готовыми proguard-конфигами. Proguard умеет заглядывать внутрь архива, находить конфиг библиотеки и добавлять его к остальным опциям. Проверьте каждую библиотеку, которую вы используете на наличие такого конфига.
(содержимое aar-файла одной из библиотек)
Если вы используете Google Play Services, то плагин com.google.gms.google-services подберет нужный вам конфиг самостоятельно.
Если авторы библиотеки не упаковывают конфиг в архив, возможно они позаботились и написали правила на своем сайте, страничке репозитория или в README файле. Попробуйте самостоятельно найти конфиг для той версии библиотеки, которую вы используете.
Если готовых правил нигде не удалось найти, придется читать логи и решать проблему индивидуально. Скорее всего, потребуется добавил keep правил для того кода библиотеки, который сломался. Или проигнорировать ошибки, если они не мешают работе программы.
Провести инспекцию своего кода
Вам виднее, какой код можно отправить под нож, но стоит внимательно взглянуть на все места, где так или иначе используется рефлексия:
- Class.forName(. ) (документация обещает, что Proguard умеет определять такой код, однако, бывали случаи, стоит проверить)
- Модельки/entity-классы, которые используются в серелизации, маппинге. Все классы, имена полей (иногда и самих классов) которых важно сохранить (Gson, RealmIO, т.п.)
- вызовы нативных библиотек через JNI
Тесты
Если какой-то класс/метод используется только в тестах и нигде больше, Proguard удалит этот код. Это обычная ситуация, если у вас TDD 🙂 На этот случай у меня есть отдельный конфиг, куда я добавляю классы, которые еще не интегрированы в проект, нигде не используются, но которые нужно протестировать.
В Android Gradle Plugin помимо proguardFiles инструкции еще есть testProguardFiles . Эта инструкция нужна для того, чтобы указать конфиги, которые будут применяться к тестовому приложению, которое генерируется для того, чтобы тестировать ваше приложение, когда вы запускаете instrumentation тесты. Обычно это применяется для того, чтобы добиться одинаковой оптимизации/обфускации в обоих apk-файлах, чтобы между ними не было рассинхронизации. Ссылка.
APK Analyzer
В Android Studio есть такой отличный инструмент. Открыть его можно или через Find Action -> Analyze APK, или открыв сам apk файл в Android Studio. Analyzer показывает много полезной информации, но сейчас нас интересует код. Что бы посмотреть что в итоге упаковалось в APK файл, нужно выбрать файл classes.dex
По умолчанию, вам будет показан именно результирующий код, прошедший шаги shrinking и optimisation. Однако, вы можете нажать на кнопку Load Proguard mappings. , добавить seeds.txt и usage.txt , чтобы увидеть код, который был удален.
Если Proguard по какой-то причине модифицировал нужный вам код, найдите его в Analyzer и через ПКМ выберите Generate Proguard Keep Rule. Analyzer сгенерирует вам на выбор несколько вариантов правил, от самого общего до самого специфичного, выберите ОДИН из них.
Для авторов библиотек
Если вы делаете Android библиотеку, вы можете добавить proguard-конфиг для своих клиентов следующим образом:
На мой взгляд, лучше не усердствовать с оптимизацией и обфускацией своей библиотеки, а предоставить эту возможность своим клиентам. Хороший тон — добавить в конфиг то, что клиентам все равно придется добавить, если они включают Proguard. Однако, если вы все-таки хотите добавить безопасности, очевидно, что нужно защитить от Proguard-а весь pulic API своей библиотеки, включая дескрипторы и сигнатуры.
R8, DexGuard и Redex
R8 — это новый инструмент от Google взамену нынешнему Proguard. Подождите, не пытайтесь забыть все, что только что прочитали в статье, просто рассматривайте это как новый Proguard. Google обещает сохранить весь public api, так что все конфиги будут работать как прежде. Проект пока в стадии beta, но вы можете попробовать его самостоятельно.
DexGuard — это платная утилита от разработчиков Proguard. Ее можно использовать вместе или вместо Proguard. Утверждается, что DexGuard умеет все, что умеет Proguard, но лучше. К сожалению, у меня не было шанса его попробовать, если у кого-то есть опыт, пожалуйста, поделитесь.
Redex — еще один dex оптимизатор от Facebook. Сообщается, что с помощью него можно добиться до 25% увеличения производительности и сокращения размера приложения, применив тулзу на уже обработанный Proguard-ом код.
Вместо заключения
Не бойтесь использовать Proguard, не поленитесь и потратьте какое-то время на настройку. Этим вы уменьшите его размер, увеличите скорость работы, чем добавите лояльности ваших юзеров. При этом старайтесь создавать эффективные Proguard-конфиги, не пишите «ковровые»» правила, иначе к вам придет разгневанный Jake Wharton и будет вас ругать.
Источник