Skip to content

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.

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.

OriginalAfter obfuscation
com.example.api.UserService.fetchUser()com.example.api.a.b()
com.example.model.Profile.userNamecom.example.model.c.a

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'

-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).

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.txt

Expected output:

com.example.api.UserService -> com.example.api.a:
void fetchUser() -> b
com.example.model.Profile -> com.example.model.c:
java.lang.String userName -> a

The 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 VersionR8 ModeNotes
< 3.4ProGuardWorks normally
3.4 – 6.xR8 compat modeExisting rules work mostly as-is
7.0 – 7.xR8 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 optimizationsSee 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.