Добавить глобальные параметры

R8 предоставляет глобальные параметры, которые либо изменяют оптимизацию R8 во всём приложении, либо затрагивают каждое правило Keep. Эти параметры хранятся в файле proguard-rules.pro вместе с правилами Keep. Некоторые из этих глобальных параметров настраивают дополнительную оптимизацию, в то время как другие отключают определённые аспекты оптимизации.

Глобальные возможности для дополнительной оптимизации

Следующие глобальные параметры обеспечивают дополнительную оптимизацию:

  • -repackageclasses [<optional-package-name>] : переупаковывает классы в один указанный пакет для дальнейшего уменьшения размера приложения. Если не указано необязательное имя пакета, классы перемещаются в пустой пакет по умолчанию. Это рекомендуемая настройка для приложений.
  • -allowaccessmodification : позволяет R8 изменять (обычно расширять) видимость классов, полей и методов для выполнения более обширной оптимизации. Включается при использовании proguard-android-optimize.txt . Начиная с версии Android Gradle Plugin (AGP) 8.2, эта конфигурация используется по умолчанию при использовании R8 в полном режиме.

Ниже приведен пример конфигурации с включенной дополнительной оптимизацией:

-repackageclasses
-allowaccessmodification

Глобальные возможности ограничения оптимизации

Следующие глобальные параметры позволяют отключить определенные аспекты оптимизации приложения и полезны при уточнении правил сохранения или первом включении R8.

  • -dontoptimize : предотвращает оптимизацию кода, например, встраивание методов. Этот параметр можно использовать во время разработки, но не следует применять в производственных сборках.
  • -dontshrink : предотвращает удаление неиспользуемого кода и оптимизаций кода. Этот параметр можно использовать во время разработки, но не следует применять в производственных сборках.
  • -dontobfuscate : предотвращает сокращение имён классов и методов. Отключение обфускации может быть особенно полезно во время отладки, чтобы облегчить чтение трассировок стека. Этот параметр можно использовать во время разработки, но не следует применять в производственных сборках.
  • -keepattributes <attributes> : принимает список атрибутов, разделённых запятыми, которые следует сохранить. Если вы не используете файл proguard-android-optimize.txt по умолчанию, R8 удаляет все атрибуты, включая RuntimeVisibleAnnotations и Signature , однако сохранение этих атрибутов может быть полезно, если они необходимы, например, для рефлексии. Список атрибутов, которые можно указать, см. в разделе Сохранение атрибутов .

Сохранить атрибуты

Атрибуты — это дополнительные фрагменты информации, прикреплённые к различным частям кода. Атрибуты хранят информацию, такую ​​как аннотации и общие сигнатуры из вашего кода.

Для успешного выполнения некоторых рефлексивных операций требуется сохранение определённых атрибутов. Например:

  • При доступе к внутренней или внешней структуре класса с помощью getEnclosingMethod() или getDeclaredClasses() необходимы атрибуты EnclosingMethod и InnerClasses .
  • При доступе к универсальным подписям с помощью getTypeParameters() необходим атрибут Signature .
  • При доступе к аннотациям с помощью getAnnotation() необходим атрибут RuntimeVisibleAnnotations .

Обычно требуемые атрибуты

При использовании файла Proguard по умолчанию ( proguard-android-optimize.txt или proguard-android.txt ) плагин Android Gradle (AGP) сохраняет следующие атрибуты. Обратите внимание, что для некоторых из этих атрибутов требуются более новые версии AGP:

Атрибут Описание
AnnotationDefault Этот атрибут обнаруживается в самих типах аннотаций и сохраняет значение по умолчанию для элемента аннотации.

Примечание: этот атрибут сохраняется по умолчанию, начиная с AGP 7.1, и его необходимо явно сохранять только в приложениях, использующих более ранние версии AGP.
EnclosingMethod Этот атрибут присутствует во внутренних классах, которые не являются локальными или анонимными. Он идентифицирует метод или инициализатор, непосредственно содержащий класс.
InnerClasses Этот атрибут записывает информацию о вложенных классах (внутренних классах, статических вложенных классах, локальных классах и анонимных классах), определенных внутри другого класса.
LineNumberTable Этот атрибут сопоставляет инструкции байт-кода с соответствующими им номерами строк в исходном файле.

Примечание: этот атрибут сохраняется по умолчанию, начиная с Android Gradle Plugin (AGP) 8.6, и его необходимо явно сохранять только в приложениях, использующих более ранние версии AGP.
RuntimeVisibleAnnotations Этот атрибут хранит аннотации, которые видны во время выполнения с помощью отражения.

Обычно, если аннотации используются во время выполнения, это единственная аннотация из атрибутов *Annotation , которая необходима приложениям и правилам потребителя библиотеки.
RuntimeVisibleParameterAnnotations Этот атрибут хранит аннотации, которые видны во время выполнения путем отражения параметров метода.
RuntimeVisibleTypeAnnotations Этот атрибут хранит аннотации, относящиеся к использованию типов, а не только к их объявлениям. Этот атрибут виден во время выполнения.
Signature Этот атрибут хранит более общую сигнатуру типа для классов, методов и полей, особенно когда они используют универсальные типы (например, List<String> ).
SourceFile Этот атрибут хранит имя исходного файла (файла .kt или .java ), из которого был скомпилирован класс. Он в основном используется отладчиками для отображения исходных строк исходного кода при пошаговом выполнении скомпилированного кода Java. Он помогает разработчикам отслеживать выполнение вплоть до написанного ими кода.

Примечание: этот атрибут сохраняется по умолчанию, начиная с AGP 8.2, и его необходимо явно сохранять только в приложениях, использующих более ранние версии AGP.

Для приложений, использующих proguard-android-optimize.txt , правил keep, определённых AGP, достаточно в большинстве случаев. Однако, если вы пишете код для библиотеки, вам следует указать все атрибуты, требуемые вашей библиотекой, в её потребительских правилах keep , даже если они определены в этом списке. Это гарантирует надёжность вашей библиотеки, если разработчики решат не включать proguard-android-optimize.txt .

Дополнительные атрибуты сохранения

Вы можете указать дополнительные атрибуты, которые необходимо сохранить, однако они не требуются для подавляющего большинства сценариев рефлексивного доступа или доступа JNI. Тем не менее, некоторые из них могут часто использоваться при оптимизации библиотек .

Атрибут Описание
MethodParameters Этот атрибут предоставляет информацию о параметрах метода, в частности об их именах и флагах доступа.
Exceptions В этом атрибуте перечислены проверенные исключения, которые, как заявлено, выдает метод.

Этот атрибут обычно не используется для приложений. Для авторов библиотек он обычно не используется в правилах хранения для потребителей, но часто применяется при сборке библиотек. Подробнее об оптимизации библиотек см. в разделе «Оптимизация для авторов библиотек» .
RuntimeInvisibleAnnotations Этот атрибут хранит аннотации, которые не видны при отражении во время выполнения для класса, поля или метода.

Разработчикам приложений не следует сохранять этот атрибут. Для авторов библиотек этот атрибут не имеет значения в правилах сохранения для потребителей, но часто используется при сборке библиотек. Подробнее об оптимизации библиотек см. в разделе «Оптимизация для авторов библиотек» .
RuntimeInvisibleParameterAnnotations Этот атрибут хранит аннотации, которые не видны при отражении во время выполнения параметров метода.

Разработчикам приложений не следует сохранять этот атрибут. Для авторов библиотек этот атрибут не имеет значения в правилах сохранения для потребителей, но часто используется при сборке библиотек. Подробнее об оптимизации библиотек см. в разделе «Оптимизация для авторов библиотек» .
RuntimeInvisibleTypeAnnotations Этот атрибут хранит аннотации, относящиеся к использованию типов, а не только к их объявлениям. Этот атрибут не отображается во время выполнения.

Разработчикам приложений не следует сохранять этот атрибут. Для авторов библиотек этот атрибут не имеет значения в правилах сохранения для потребителей, но часто используется при сборке библиотек. Подробнее об оптимизации библиотек см. в разделе «Оптимизация для авторов библиотек» .