Stay organized with collections
Save and categorize content based on your preferences.
When you enable app optimization with the default settings, R8 performs
extensive optimizations in order to maximize your performance benefits. R8 makes
substantial modifications to the code including renaming, moving, and removing
classes, fields and methods. If you observe that these modifications cause
errors, you need to specify which parts of the code R8 shouldn't modify by
declaring those in keep rules.
Common scenarios that require keep rules
R8 identifies and preserves all direct calls in your code. However, R8 cannot
see indirect code usages, which can cause it to remove code that your app needs,
causing crashes. Use keep rules to tell R8 to preserve such indirectly used
code. A few common situations where you are likely to need keep rules are as
follows:
Code accessed by reflection: R8 can't identify when classes, fields or
methods are accessed with reflection. For example, R8 cannot identify a
method looked up by its name using Class.getDeclaredMethod() or an
annotation retrieved with Class.getAnnotation(). In these cases, R8 might
rename these methods and annotations or remove them entirely, leading to a
ClassNotFoundException or a NoSuchMethodException at runtime.
Code called from Java Native Interface (JNI): When native (C or C++) code
calls a Java or Kotlin method, or Java or Kotlin code calls C++ code with
JNI, the call is based on a dynamic string lookup of the method's name. R8
can't see the dynamic string-based method call, and so its optimizations
might break your code.
This is not an exhaustive list of scenarios that require keep rules, but these
scenarios cover most of the cases where you might need keep rules.
How to add keep rules to your app
You should add your rules to a proguard-rules.pro file located in the app
module's root directory—the file might already be there, but if it isn't, create
it. To apply the rules in the file, you must declare the file in your
module-level build.gradle.kts (or build.gradle) file as shown in the
following code:
Kotlin
android{buildTypes{release{isMinifyEnabled=trueisShrinkResources=trueproguardFiles(// File with default rules provided by the Android Gradle PlugingetDefaultProguardFile("proguard-android-optimize.txt"),// File with your custom rules"proguard-rules.pro")// ...}}// ...}
Groovy
android{buildTypes{release{minifyEnabledtrueshrinkResourcestrueproguardFiles(// File with default rules provided by the Android Gradle PlugingetDefaultProguardFile('proguard-android-optimize.txt'),// File with your custom rules.'proguard-rules.pro')// ...}}// ...}
By default, your build file also includes the proguard-android-optimize.txt
file. This file includes rules that are required for most Android projects, so
you should let it remain in the build file. This file is based on, and shares
content with, the proguard-common.txt file.
Larger apps typically have code in multiple library modules. In such cases, it's
often better to put the keep rules alongside the code they apply to within the
specific library module. The crucial difference in maintaining keep rules for
libraries lies in how you declare these rules within your library module's
build.gradle.kts (or build.gradle) file. See Optimization for library
authors to learn more.
Add a keep rule
When you add keep rules, you can include global options as well as define your
own keep rules.
Global options: Global options are general directives that affect how R8
operates on your entire codebase. To learn more, see Global options.
Keep rules: Keep rules need to be designed carefully, to make sure you
get the right balance between maximizing code optimization without
inadvertently breaking your app. To learn the syntax for your own keep
rules, see Keep rules syntax.
Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
Last updated 2025-08-21 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-21 UTC."],[],[],null,["# About keep rules\n\nWhen you [enable app optimization](/topic/performance/app-optimization/enable-app-optimization) with the default settings, R8 performs\nextensive optimizations in order to maximize your performance benefits. R8 makes\nsubstantial modifications to the code including renaming, moving, and removing\nclasses, fields and methods. If you observe that these modifications cause\nerrors, you need to specify which parts of the code R8 *shouldn't* modify by\ndeclaring those in keep rules.\n| **Note:** Keep rules that are narrowly scoped allow for maximum optimization. Use keep rules that are as specific as possible if rules are necessary, or consider a change in libraries if usage of a library is causing problems with R8 optimizations.\n\nCommon scenarios that require keep rules\n----------------------------------------\n\nR8 identifies and preserves all direct calls in your code. However, R8 cannot\nsee indirect code usages, which can cause it to remove code that your app needs,\ncausing crashes. Use keep rules to tell R8 to preserve such indirectly used\ncode. A few common situations where you are likely to need keep rules are as\nfollows:\n\n- Code accessed by reflection: R8 can't identify when classes, fields or methods are accessed with reflection. For example, R8 cannot identify a method looked up by its name using `Class.getDeclaredMethod()` or an annotation retrieved with `Class.getAnnotation()`. In these cases, R8 might rename these methods and annotations or remove them entirely, leading to a `ClassNotFoundException` or a `NoSuchMethodException` at runtime.\n- Code called from Java Native Interface (JNI): When native (C or C++) code calls a Java or Kotlin method, or Java or Kotlin code calls C++ code with JNI, the call is based on a dynamic string lookup of the method's name. R8 can't see the dynamic string-based method call, and so its optimizations might break your code.\n\nThis is not an exhaustive list of scenarios that require keep rules, but these\nscenarios cover most of the cases where you might need keep rules.\n| **Note:** In modern Android development, you should limit the use of reflection and avoid calls from native code into your Java or Kotlin code where possible because these code patterns can impact performance. When selecting dependencies for your app, choose libraries that are compatible with R8 optimization. To learn more, see [Choose libraries wisely](/topic/performance/app-optimization/choose-libraries-wisely).\n\nHow to add keep rules to your app\n---------------------------------\n\nYou should add your rules to a `proguard-rules.pro` file located in the app\nmodule's root directory---the file might already be there, but if it isn't, create\nit. To apply the rules in the file, you must declare the file in your\nmodule-level `build.gradle.kts` (or `build.gradle`) file as shown in the\nfollowing code: \n\n### Kotlin\n\n```kotlin\nandroid {\n buildTypes {\n release {\n isMinifyEnabled = true\n isShrinkResources = true\n\n proguardFiles(\n // File with default rules provided by the Android Gradle Plugin\n getDefaultProguardFile(\"proguard-android-optimize.txt\"),\n\n // File with your custom rules\n \"proguard-rules.pro\"\n )\n // ...\n }\n }\n // ...\n}\n```\n\n### Groovy\n\n```groovy\nandroid {\n buildTypes {\n release {\n minifyEnabled true\n shrinkResources true\n\n proguardFiles(\n // File with default rules provided by the Android Gradle Plugin\n getDefaultProguardFile('proguard-android-optimize.txt'),\n\n // File with your custom rules.\n 'proguard-rules.pro'\n )\n // ...\n }\n }\n // ...\n}\n```\n\nBy default, your build file also includes the `proguard-android-optimize.txt`\nfile. This file includes rules that are required for most Android projects, so\nyou should let it remain in the build file. This file is based on, and shares\ncontent with, the [`proguard-common.txt`](https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/resources/com/android/build/gradle/proguard-common.txt) file.\n| **Warning:** You might find that older Android projects still use `proguard-android.txt` instead of `proguard-android-optimize.txt` as their default R8 configuration. If your project uses the `proguard-android.txt` file as its default R8 configuration, you should migrate to the `proguard-android-optimize.txt` file. The `proguard-android.txt` file has legacy configurations that prevent most optimizations.\n\nLarger apps typically have code in multiple library modules. In such cases, it's\noften better to put the keep rules alongside the code they apply to within the\nspecific library module. The crucial difference in maintaining keep rules for\nlibraries lies in how you declare these rules within your library module's\n`build.gradle.kts` (or `build.gradle`) file. See [Optimization for library\nauthors](/topic/performance/app-optimization/library-optimization) to learn more.\n| **Note:** To learn how to optimize resources, see [Customize which resources to\n| keep](/topic/performance/app-optimization/customize-which-resources-to-keep).\n\nAdd a keep rule\n---------------\n\nWhen you add keep rules, you can include global options as well as define your\nown keep rules.\n\n- **Global options** : Global options are general directives that affect how R8 operates on your entire codebase. To learn more, see [Global options](/topic/performance/app-optimization/global-options).\n- **Keep rules** : Keep rules need to be designed carefully, to make sure you get the right balance between maximizing code optimization without inadvertently breaking your app. To learn the syntax for your own keep rules, see [Keep rules syntax](/topic/performance/app-optimization/keep-rules-syntax).\n\n| **Note:** Keep rules are additive-they are merged from all sources. You can see which rules are applied to confirm that the consolidated keep rules are having the intended effect. To learn more, see [Check which rules are applied](/topic/performance/app-optimization/test-and-troubleshoot-the-optimization#check-which-rules-are-applied).\n\nKeep rules for library authors\n------------------------------\n\nAfter learning about the global options and syntax for keep rules, see\n[Optimization for library authors](/topic/performance/app-optimization/library-optimization) for further details."]]