Best Practices
Recommendations for integrating Shield into your Android development workflow and deploying protected applications to production.
Start Incrementally
Do not enable all 9 protections at once. Start with the safest protections and add more as you verify each one works with your application:
Phase 1: Safe Baseline
protections {
stringEncryption = true
constantMutation = true
debugRemoval = true
}protections {
stringEncryption = true
constantMutation = true
debugRemoval = true
}These three protections have the lowest risk of causing runtime issues. Build, test, and ship with this configuration first.
Phase 2: Code Obfuscation
shield {
preset("mobile")
protections {
controlFlowObfuscation = true
}
}shield {
preset("mobile")
protections {
controlFlowObfuscation = true
}
}Add control flow on top of the mobile preset. Test thoroughly — if any issues appear, use @Exclude on affected methods or per-protection exclusions like excludePackages("com.example.ui:ControlFlowMatrix").
Phase 3: Runtime Protections
shield {
preset("mobile")
protections {
controlFlowObfuscation = true
antiTamper = true
}
}shield {
preset("mobile")
protections {
controlFlowObfuscation = true
antiTamper = true
}
}Add anti-tamper last. It is the most likely to cause issues during development (anti-debug already comes with the mobile preset but blocks Android Studio debugger, anti-tamper fails on modified debug APKs).
Phase 4: Maximum Protection
shield {
preset("aggressive")
// If R8 is enabled:
protections { nameObfuscation = false }
}shield {
preset("aggressive")
// If R8 is enabled:
protections { nameObfuscation = false }
}Use the aggressive preset for maximum protection. If R8 is enabled, override nameObfuscation = false to let R8 handle renaming.
Variant Strategy
Always use variant configuration to separate development from production:
shield {
variant("debug") {
protections {
antiDebug = false
}
}
variant("release") {
preset("aggressive")
}
}shield {
variant("debug") {
protections {
antiDebug = false
}
}
variant("release") {
preset("aggressive")
}
}This lets you develop without Shield-related friction while ensuring releases are fully protected.
Exclude Aggressively at First
Shield automatically excludes Android, Kotlin, and other common framework packages. For any additional third-party libraries, add them explicitly:
excludePackages(
"com.google",
"com.squareup",
"dagger",
"javax.inject",
"io.reactivex",
"org.reactivestreams"
)excludePackages(
"com.google",
"com.squareup",
"dagger",
"javax.inject",
"io.reactivex",
"org.reactivestreams"
)Only your application code should be processed by Shield. Third-party libraries are already compiled and should be excluded. You can also use per-protection exclusions to selectively exclude packages from specific protections only.
Test Every Build
After enabling Shield:
- Run your test suite against the protected APK, not just the unprotected one
- Test on real devices — emulators may trigger anti-debug detection
- Test serialization — Verify JSON parsing, database operations, and API calls
- Test deep links and intents — These rely on class names in the manifest
- Monitor crash rates after deploying a new protection to production
Token Management
- Use environment variables for project tokens in CI/CD
- Never commit tokens to version control
- Rotate tokens from the Cloud Panel if they are exposed
- Each project should have its own token
R8 Strategy
For most projects with R8 enabled:
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
}
}
}
shield {
protections {
nameObfuscation = false // R8 handles this
// Enable all other Shield protections
}
}android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
}
}
}
shield {
protections {
nameObfuscation = false // R8 handles this
// Enable all other Shield protections
}
}R8 handles code shrinking and basic renaming. Shield handles everything R8 cannot: string encryption, control flow, anti-debug, anti-tamper, and more.
Keep Mapping Files
Mapping files are critical for debugging production crashes. Shield uploads them to the Cloud Panel automatically, but also consider:
- Storing mapping files as CI/CD artifacts
- Uploading to Firebase Crashlytics
- Archiving mapping files for every release version
Related
- Protections Overview — What each protection does
- Troubleshooting — Fixing common issues
- Variant Configuration — Per-build-type settings
- Mapping Files — Stack trace deobfuscation