About keep rules

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 = true
            isShrinkResources = true

            proguardFiles(
                // File with default rules provided by the Android Gradle Plugin
                getDefaultProguardFile("proguard-android-optimize.txt"),

                // File with your custom rules
                "proguard-rules.pro"
            )
           // ...
        }
    }
    // ...
}

Groovy

android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true

            proguardFiles(
                // File with default rules provided by the Android Gradle Plugin
                getDefaultProguardFile('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.

Keep rules for library authors

After learning about the global options and syntax for keep rules, see Optimization for library authors for further details.