tezvyn:

ProGuard Keep Rules: A "Do Not Remove" List for Your Code

AI-drafted, machine-checkedSource: developer.android.comintermediate
ProGuard Keep Rules: A "Do Not Remove" List for Your Code

ProGuard keep rules are a "do not remove" list for Android's code shrinker, telling it what to spare when it can't detect usage. This is crucial for code accessed via reflection or JNI.

WHY IT EXISTS: To reduce your app's size, Android's build tools use a shrinker (like ProGuard or R8) to remove unused code. However, this automated process can't always detect code that is used indirectly, such as through reflection. Removing this "invisibly" used code causes your app to crash at runtime. Keep rules exist to prevent this.

THE MENTAL MODEL: Think of keep rules as a "do not remove" list you give to an aggressive decluttering service. The service (R8) automatically throws away anything it thinks is junk. Your list tells it, "Even though you don't see me using this item, it's an heirloom. Do not throw it away." You are manually overriding the automated logic to prevent mistakes.

HOW IT WORKS: You define these rules in a proguard-rules.pro file using a specific syntax. A rule like -keep class com.example.MyModel { *; } instructs the shrinker to preserve the MyModel class and all of its members (fields and methods) from being removed or renamed (obfuscated). Many third-party libraries that use reflection already include their own keep rules, which are automatically applied to your build.

WHEN TO USE IT: You need keep rules primarily in three situations. First, when your app uses reflection to access code by its string name, which is common with serialization libraries like Gson or Moshi. Second, when interacting with native code through the Java Native Interface (JNI), as the build tools can't see calls from C/C++ into your Java/Kotlin code. Third, for any classes that are only referenced in Android Manifest files or XML layouts, like custom Views.

WHEN NOT TO USE IT: You don't need keep rules for code that is directly called from other parts of your app's source. The biggest anti-pattern is writing overly broad rules, like -keep class com.example.** { *; }, which effectively disables shrinking for an entire package. Be as specific as possible, as broad rules defeat the purpose of using a shrinker.

ONE CANONICAL EXAMPLE: A data class used for JSON parsing with a library like Gson. Gson uses reflection to create objects and set their fields from a JSON string. Without a keep rule, R8 might remove the class's empty constructor or fields, causing a runtime crash. A rule like -keep class com.myapp.data.User { <init>; public *; } ensures the User class, its constructor, and all its public members are preserved.

Read the original → developer.android.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.