Add global options

R8 provides global options that either modify R8's optimizations throughout the app or affect every keep rule. These options are maintained in the proguard-rules.pro file, along with keep rules. A few of these global options configure additional optimization, while others turn off certain aspects of the optimization.

Global options for additional optimization

The following global options enable additional optimization:

  • -repackageclasses [<optional-package-name>]: Repackages classes into a single, specified package, for further app size reduction. If you don't supply the optional package name, the classes are moved into the empty, default package. This is a recommended setting for apps.
  • -allowaccessmodification: Lets R8 change (typically widen) the visibility of classes, fields, and methods to perform more extensive optimizations. Enabled when proguard-android-optimize.txt is used. Since Android Gradle Plugin (AGP) 8.2, this is the default configuration if you use R8 in full mode.

The following is an example of a configuration with additional optimization enabled:

-repackageclasses
-allowaccessmodification

Global options to limit optimization

The following global options let you turn off certain aspects of app optimization, and are helpful when you're refining your keep rules or turning on R8 for the first time.

  • -dontoptimize: Prevents code optimization, for example method inlining. This option can be used during development but shouldn't be used in production builds.
  • -dontshrink: Prevents the removal of unreferenced code and code optimizations. This option can be used during development but shouldn't be used in production builds.
  • -dontobfuscate: Prevents shortening the names of classes and methods. It can be especially helpful to turn off obfuscation during debugging so stack traces are easier to read. This option can be used during development but shouldn't be used in production builds.
  • -keepattributes <attributes>: Accepts a comma-separated list of attributes that should be preserved. If you're not using the default proguard-android-optimize.txt, R8 strips all attributes including RuntimeVisibleAnnotations and Signature, however it can be helpful to preserve these attributes if they are needed in cases like reflection. For a list of attributes you can specify, see Keep attributes.

Keep attributes

Attributes are extra pieces of information attached to different parts of your code. Attributes store information like annotations and generic signatures from your code.

Certain reflective operations require specific attributes to be kept for successful execution. For example:

  • When accessing the inner or outer class structure using getEnclosingMethod() or getDeclaredClasses(), the attributes EnclosingMethod and InnerClasses are needed.
  • When accessing generic signatures using getTypeParameters(), the attribute Signature is needed.
  • When accessing annotations using getAnnotation(), the attribute RuntimeVisibleAnnotations is needed.

Commonly required attributes

When using the default Proguard file (proguard-android-optimize.txt or proguard-android.txt), the Android Gradle plugin (AGP) keeps the following attributes. Note that some of these attributes require newer versions of AGP:

Attribute Description
AnnotationDefault This attribute is found on annotation types themselves and stores the default value for an annotation element.

Note: This attribute is kept by default since AGP 7.1, and only needs to be explicitly kept in apps using earlier versions of AGP.
EnclosingMethod This attribute is present in inner classes that are not local or anonymous classes. It identifies the method or initializer that immediately contains the class.
InnerClasses This attribute records information about nested classes (inner classes, static nested classes, local classes, and anonymous classes) defined within another class.
LineNumberTable This attribute maps bytecode instructions to their corresponding line numbers in the original source file.

Note: This attribute is kept by default since Android Gradle Plugin (AGP) 8.6, and only needs to be explicitly kept in apps using earlier versions of AGP.
RuntimeVisibleAnnotations This attribute stores annotations that are visible at runtime by reflection.

Typically, if annotations are used at runtime, this is the only annotation from the *Annotation attributes that is needed by apps and in library consumer rules.
RuntimeVisibleParameterAnnotations This attribute stores annotations that are visible at runtime by reflection on the parameters of a method.
RuntimeVisibleTypeAnnotations This attribute stores annotations that apply to type uses rather than just declarations. This attribute is visible at runtime.
Signature This attribute stores a more generic type signature for classes, methods, and fields, particularly when they use generics (like List<String>).
SourceFile This attribute stores the name of the source file (.kt or .java file) from which a class was compiled. It is primarily used by debuggers to display the original source code lines when stepping through compiled Java code. It helps developers trace execution back to their written code.

Note: This attribute is kept by default since AGP 8.2, and only needs to be explicitly kept in apps using earlier versions of AGP.

For apps that use proguard-android-optimize.txt, the keep rules defined by AGP are adequate in most scenarios. However, if you are writing code for a library, you should specify all the attributes required by your library in its consumer keep rules, even if they are defined in this list. This makes sure that your library is robust if developers decide not to include proguard-android-optimize.txt.

Additional keep attributes

You can specify additional attributes to be kept, however they are not needed for the vast majority of reflective or JNI access scenarios. However, some of these might still frequently be used while optimizing libraries.

Attribute Description
MethodParameters This attribute provides information about the parameters of a method, specifically their names and access flags.
Exceptions This attribute lists the checked exceptions that a method is declared to throw.

This attribute is not typically used for apps. For library authors, it is not typically used in consumer keep rules, but is often used when building libraries. For details about optimizing libraries, see Optimization for library authors.
RuntimeInvisibleAnnotations This attribute stores annotations that are not visible with reflection at runtime on a class, field, or method.

App developers shouldn't keep this attribute. For library authors, this attribute is not relevant in consumer keep rules, but is often used when building libraries. For details about optimizing libraries, see Optimization for library authors.
RuntimeInvisibleParameterAnnotations This attribute stores annotations that are not visible with reflection at runtime on the parameters of a method.

App developers shouldn't keep this attribute. For library authors, this attribute is not relevant in consumer keep rules, but is often used when building libraries. For details about optimizing libraries, see Optimization for library authors.
RuntimeInvisibleTypeAnnotations This attribute stores annotations that apply to type uses rather than just declarations. This attribute is not visible at runtime.

App developers shouldn't keep this attribute. For library authors, this attribute is not relevant in consumer keep rules, but is often used when building libraries. For details about optimizing libraries, see Optimization for library authors.