О правилах хранения

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

Распространенные сценарии, в которых требуются правила хранения

R8 определяет и сохраняет все прямые вызовы в коде. Однако R8 не может видеть косвенное использование кода, что может привести к удалению кода, необходимого вашему приложению, и вызвать сбои. Используйте правила сохранения, чтобы указать R8, что такой косвенно используемый код нужно сохранить. Ниже приведены распространенные ситуации, в которых могут потребоваться правила хранения.

  • Код, доступ к которому осуществляется с помощью рефлексии. R8 не может определить, когда доступ к классам, полям или методам осуществляется с помощью рефлексии. Например, R8 не может идентифицировать метод, найденный по имени с помощью Class.getDeclaredMethod(), или аннотацию, полученную с помощью Class.getAnnotation(). В таких случаях R8 может переименовать эти методы и аннотации или полностью удалить их, что приведет к ошибке ClassNotFoundException или NoSuchMethodException во время выполнения.
  • Код, вызываемый из Java Native Interface (JNI). Когда нативный код (C или C++) вызывает метод Java или Kotlin, или код Java или Kotlin вызывает код C++ с помощью JNI, вызов основан на динамическом поиске строки по названию метода. R8 не может распознать динамический вызов метода на основе строки, поэтому оптимизация может нарушить работу кода.

Это не исчерпывающий список сценариев, в которых требуются правила хранения, но он охватывает большинство случаев, когда они могут понадобиться.

Если ваш код использует рефлексию или вызывается из JNI, вы можете добавить в него аннотации Jetpack Keep вместо того, чтобы вручную писать правила сохранения. Его плагин Gradle генерирует правила сохранения из аннотаций во время сборки.

Как добавить правила сохранения в приложение

Конфигурация правил сохранения зависит от используемой версии AGP.

В крупных приложениях код обычно хранится в нескольких модулях библиотеки. В таких случаях лучше размещать правила сохранения рядом с кодом, к которому они применяются, в определенном модуле библиотеки. Основное отличие в поддержке правил сохранения для библиотек заключается в том, как вы объявляете эти правила в файле build.gradle.kts (или build.gradle) модуля библиотеки. Подробнее об оптимизации для авторов библиотек…

Для AGP версии 9.3 и более поздних

Добавьте правила в файл с суффиксом .keep в каталоге src/<variant>/keepRules. Пример: src/main/keepRules/custom-rules.keep. Обратите внимание, что при использовании обновленного DSL для AGP 9.3 и более поздних версий оптимизация кода и ресурсов выполняется автоматически. Вам не нужно явно указывать файл правил сохранения Android по умолчанию (proguard-android-optimize.txt), поскольку он включен по умолчанию, если только вы не исключили его явным образом.

Kotlin

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
            }
        }
    }
}

Яркий

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
            }
        }
    }
}

Пропустить правила хранения платформы Android по умолчанию (расширенная настройка)

AGP предоставляет набор правил платформы Android по умолчанию. Чтобы исключить эти правила из конфигурации проекта и управлять всеми правилами хранения самостоятельно, задайте для параметра optimization.keepRules.includeDefault значение false.

Kotlin

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
                keepRules {
                    includeDefault = false // The file with optimization
                    // rules for the Android platform is included by
                    // default. To omit this file, set this option to false.
                }
            }
        }
    }
}

Яркий

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
                keepRules {
                    includeDefault = false // The file with optimization
                    // rules for the Android platform is included by
                    // default. To omit this file, set this option to false.
                }
            }
        }
    }
}

Устаревший DSL для версий AGP ниже 9.3

Добавьте правила в файл proguard-rules.pro, расположенный в корневом каталоге модуля приложения. Если такого файла нет, создайте его. Чтобы применить правила из файла, необходимо объявить его в файле build.gradle.kts (или build.gradle) на уровне модуля.

По умолчанию файл сборки также включает файл proguard-android-optimize.txt. Этот файл содержит правила, необходимые для большинства проектов для Android, поэтому его следует оставить в файле сборки. Этот файл основан на файле proguard-common.txt и содержит тот же контент.

Устаревший DSL (Kotlin)

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            isShrinkResources = true

            proguardFiles(
                // Default file with default optimization rules.
                getDefaultProguardFile("proguard-android-optimize.txt"),
                ...
            )
        }
    }
}

Устаревший DSL (Groovy)

android {
    buildTypes {
        release {
            minifyEnabled = true
            shrinkResources = true

            // Default file with default optimization rules.
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
            ...
        }
    }
}

Как добавить правило хранения

При добавлении правил хранения можно использовать глобальные параметры, а также задавать собственные правила.

  • Глобальные параметры. Это общие директивы, которые влияют на то, как R8 работает со всей базой кода. Подробнее о глобальных настройках…

  • Правила сохранения. Их нужно тщательно продумать, чтобы найти баланс между оптимизацией кода и стабильностью работы приложения. Подробнее о том, как добавлять правила сохранения…

Сохранить правила для авторов библиотеки

После того как вы изучите глобальные параметры и синтаксис правил сохранения, ознакомьтесь с информацией об оптимизации для авторов библиотек.