Что на самом деле делает полный режим R8 (агрессивная оптимизация)? - PullRequest
2 голосов
/ 06 ноября 2019

В официальной документации R8 сказано, что для активации дополнительных оптимизаций я должен вставить это в файл gradle.properties:

android.enableR8.fullMode=true

В документации сказано, что для того, чтобы приложениеЯ должен установить некоторые правила хранения, но нет подробных сведений о том, как он работает и какие действия он выполняет:

Поскольку из-за дополнительных оптимизаций R8 ведет себя иначе, чем ProGuard, они могут потребовать, чтобы вы добавили дополнительныеПравила ProGuard, чтобы избежать проблем во время выполнения. Например, скажем, что ваш код ссылается на класс через API Reflection Java. По умолчанию R8 предполагает, что вы намереваетесь исследовать объекты этого класса и манипулировать ими во время выполнения, даже если вы на самом деле этого не делаете, и автоматически сохраняет класс и его статический инициализатор.

Однако при использовании «fullmode ”, R8 не делает этого предположения, и, если R8 утверждает, что ваш код иначе никогда не использует класс во время выполнения, он удаляет класс из окончательного DEX вашего приложения. То есть, если вы хотите сохранить класс и его статический инициализатор, вам нужно включить правило сохранения в файл правил, чтобы сделать это.

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

полный режим R8

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

Как работает android.enableR8.fullMode на самом деле?

Большое спасибо!

1 Ответ

1 голос
/ 07 ноября 2019

Это правда, что документация полного режима отсутствует. В настоящее время он состоит в основном из следующего:

  • Не сохраняйте конструкторы по умолчанию (<init>()) для типов, которые сохраняются, если методы <init> не сохраняются вообще, в этом случае по умолчаниюконструкторы (<init>()) будут сохранены
  • Не сохранять конструкторы по умолчанию (<init>()) для типов, которые используются только с приведениями (checkcast байтовый код)
  • Несохранить конструкторы по умолчанию (<init>()) для типов, которые используются только с instanceof (instanceof байтовый код)
  • Не сохранять код для целевых (но не живых) методов по умолчанию, сделать их абстрактными
  • Не храните все прямые методы в иерархии (сохраняйте только тот, который соответствует)
  • Сохраняйте меньше атрибутов для типов, которые не соответствуют правилам хранения, даже если указано -keepattributes. В настоящее время он в основном нацелен на атрибуты, связанные с внутренними / внешними отношениями (InnerClass и EnclosingMethod).

Это основные различия, но их может быть несколько. Мы работаем над добавлением более конкретной документации, но это все еще движущаяся цель.

Обратите внимание, если правила хранения для программы завершены в том смысле, что все, что используется отражением, покрыто правилом хранения. , то включение android.enableR8.fullMode не должно вызывать проблем. Тем не менее, мы часто видим конфигурации, где эти (также не документированные) соглашения от Proguard заставляют конфигурацию работать.

...