ProGuard Setup for Dex Protection
When Dex Protection is enabled, DoveRunner identifies your business code by locating packages declared in the APK/AAB manifest. If ProGuard or R8 has repackaged those classes elsewhere, DoveRunner may not be able to find them — and they won’t be obfuscated.
The fix is a single rule that tells ProGuard/R8 to preserve your package structure while still obfuscating class and member names.
Required Rule
Section titled “Required Rule”Add the following to your proguard-rules.pro, replacing com.example with your app’s base package name:
-keeppackagenames 'com.example.**'This preserves the package path as-is while class, method, and field names are still obfuscated normally.
| Original | After obfuscation |
|---|---|
com.example.api.UserService.fetchUser() | com.example.api.a.b() |
com.example.model.Profile.userName | com.example.model.c.a |
Rules to Avoid
Section titled “Rules to Avoid”The following rules relocate or flatten package paths and will break the package structure that DoveRunner relies on. Avoid using them alongside -keeppackagenames:
-repackageclasses 'x'-flattenpackagehierarchy 'x'Library Compatibility
Section titled “Library Compatibility”-keeppackagenames only preserves package paths — class and member names are still obfuscated. Some libraries require additional ProGuard rules to function correctly at runtime (for example, libraries that rely on reflection or serialization).
If a library you use provides its own required ProGuard rules, apply them as-is. -keeppackagenames does not interfere with standard -keep rules for specific classes or members, so there is no conflict as long as you avoid the package-relocating rules listed above (-repackageclasses, -flattenpackagehierarchy).
Verifying the Setup
Section titled “Verifying the Setup”After a release build, open the mapping file and confirm that package paths are preserved while class names are obfuscated:
app/build/outputs/mapping/release/mapping.txtExpected output:
com.example.api.UserService -> com.example.api.a: void fetchUser() -> bcom.example.model.Profile -> com.example.model.c: java.lang.String userName -> aThe package path (com.example.api, com.example.model) must be intact, and class/member names must be replaced with short symbols.
AGP version compatibility details
-keeppackagenames works correctly across all AGP versions. The main difference is how aggressively R8 optimizes in each mode.
| AGP Version | R8 Mode | Notes |
|---|---|---|
| < 3.4 | ProGuard | Works normally |
| 3.4 – 6.x | R8 compat mode | Existing rules work mostly as-is |
| 7.0 – 7.x | R8 full mode (opt-in) | Enable via android.enableR8.fullMode=true |
| 8.0+ | R8 full mode (default) | More aggressive: class merging, inlining |
| 9.x+ | R8 full mode + extra optimizations | See official release notes |
In R8 full mode, some classes inside a preserved package may disappear due to merging or inlining. This is expected behavior and does not affect DoveRunner’s ability to identify and obfuscate the package — as long as surviving classes retain their package paths.