Как автор библиотеки, вы должны убедиться, что разработчики приложений могут легко включить вашу библиотеку в свое приложение, сохраняя при этом высокое качество конечного пользовательского опыта. Вы должны убедиться, что ваша библиотека совместима с оптимизацией Android без дополнительной настройки — или документировать, что библиотека может быть неподходящей для использования на Android.
Эта документация предназначена для разработчиков опубликованных библиотек, но может быть также полезна для разработчиков внутренних библиотечных модулей в больших модульных приложениях.
Если вы разработчик приложений и хотите узнать об оптимизации вашего приложения Android, см. Включить оптимизацию приложения . Чтобы узнать, какие библиотеки подходят для использования, см. Выбирайте библиотеки с умом .
Используйте кодогенерацию вместо рефлексии
По возможности используйте генерацию кода ( codegen ) вместо рефлексии. Codegen и рефлексия — это распространенные подходы, позволяющие избежать шаблонного кода при программировании, но codegen более совместим с оптимизатором приложений, таким как R8:
- С помощью codegen код анализируется и модифицируется в процессе сборки. Поскольку после компиляции не происходит никаких серьезных изменений, оптимизатор знает, какой код в конечном итоге нужен, а что можно безопасно удалить.
- С рефлексией код анализируется и обрабатывается во время выполнения. Поскольку код на самом деле не финализирован до тех пор, пока не будет выполнен, оптимизатор не знает, какой код можно безопасно удалить. Скорее всего, он удалит код, который динамически используется через рефлексию во время выполнения, что приводит к сбоям приложения у пользователей.
Многие современные библиотеки используют codegen вместо reflect. Смотрите KSP для общей точки входа, используемой Room , Dagger2 и многими другими.
Когда рефлексия — это нормально
Если вам необходимо использовать отражение, вы должны отражать только одно из следующих:
- Конкретные целевые типы (конкретные реализаторы интерфейсов или подклассы)
- Код, использующий определенную аннотацию времени выполнения
Использование отражения таким образом ограничивает затраты времени выполнения и позволяет писать целевые правила хранения для потребителей .
Эта конкретная и целенаправленная форма отражения является шаблоном, который вы можете увидеть как в фреймворке Android (например, при инфляции действий, представлений и рисунков), так и в библиотеках AndroidX (например, при построении WorkManager ListenableWorkers или RoomDatabases). Напротив, открытое отражение Gson не подходит для использования в приложениях Android .
Напишите правила хранения для потребителей
Библиотеки должны упаковывать "потребительские" правила хранения, которые используют тот же формат, что и правила хранения приложений. Эти правила объединяются в артефакты библиотеки (AAR или JAR) и автоматически используются во время оптимизации приложения Android при использовании библиотеки.
AAR-библиотеки
Чтобы добавить потребительские правила для библиотеки AAR, используйте опцию consumerProguardFiles
в скрипте сборки модуля библиотеки Android. Для получения дополнительной информации см. наше руководство по созданию модулей библиотеки .
Котлин
android { defaultConfig { consumerProguardFiles("consumer-proguard-rules.pro") } ... }
Круто
android { defaultConfig { consumerProguardFiles 'consumer-proguard-rules.pro' } ... }
JAR-библиотеки
Чтобы связать правила с вашей библиотекой Kotlin/Java, которая поставляется как JAR, поместите файл правил в конечный каталог JAR META-INF/proguard/
с любым именем файла. Например, если ваш код в <libraryroot>/src/main/kotlin
, поместите файл правил потребителя в <libraryroot>/src/main/resources/META-INF/proguard/consumer-proguard-rules.pro
, и правила будут объединены в правильном месте в вашем выходном JAR.
Убедитесь, что окончательный JAR-файл правильно объединяет правила, проверив, находятся ли правила в каталоге META-INF/proguard
.
Поддержка различных усадочных машин (расширенная)
Вы можете адаптировать правила для конкретных целеуказаний (R8 или ProGuard), а также для конкретных версий кратеров. Это позволяет вашей библиотеке оптимально работать в проектах, использующих новые версии кратеров, в то же время позволяя существующим правилам продолжать использоваться в проектах со старыми версиями кратеров.
Чтобы указать целевые правила сжатия, вам необходимо включить их в определенные места внутри библиотеки AAR или JAR, как описано ниже.
In an AAR library:
consumer-proguard-rules.pro (legacy location)
classes.jar
└── META-INF
└── com.android.tools (targeted shrink rules location)
├── r8-from-<X>-upto-<Y>/<R8-rules-file>
└── proguard-from-<X>-upto-<Y>/<ProGuard-rules-file>
In a JAR library:
META-INF
├── proguard/<ProGuard-rules-file> (legacy location)
└── com.android.tools (targeted shrink rules location)
├── r8-from-<X>-upto-<Y>/<R8-rules-file>
└── proguard-from-<X>-upto-<Y>/<ProGuard-rules-file>
Это означает, что целевые правила сжатия хранятся в каталоге META-INF/com.android.tools
JAR-файла или в каталоге META-INF/com.android.tools
внутри classes.jar
AAR-файла.
В этом каталоге может быть несколько каталогов с именами в форме r8-from-<X>-upto-<Y>
или proguard-from-<X>-upto-<Y>
чтобы указать, для каких версий какого сжимателя написаны правила внутри каталогов. Обратите внимание, что части - from-<X>
и - upto-<Y>
являются необязательными, версия <Y>
является исключительной , а диапазоны версий должны быть непрерывными.
Например, r8-upto-8.0.0, r8-from-8.0.0-upto-8.2.0
и r8-from-8.2.0
образуют допустимый набор целевых правил сжатия. Правила в каталоге r8-from-8.0.0-upto-8.2.0
будут использоваться R8 с версии 8.0.0 до версии 8.2.0, но не включая ее .
Учитывая эту информацию, плагин Android Gradle выбирает правила из соответствующих каталогов R8. Если библиотека не указывает целевые правила сжатия, плагин Android Gradle выберет правила из устаревших расположений ( proguard.txt
для AAR или META-INF/proguard/<ProGuard-rules-file>
для JAR).