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
protections {
stringEncryption = true
constantMutation = true
debugRemoval = true
controlFlowObfuscation = true
referenceProxy = true
}protections {
stringEncryption = true
constantMutation = true
debugRemoval = true
controlFlowObfuscation = true
referenceProxy = true
}Add control flow and reference proxy. Test thoroughly — if any issues appear, use @Exclude on affected methods.
Phase 3: Runtime Protections
protections {
stringEncryption = true
constantMutation = true
debugRemoval = true
controlFlowObfuscation = true
referenceProxy = true
antiDebug = true
antiTamper = true
resourceProtection = true
}protections {
stringEncryption = true
constantMutation = true
debugRemoval = true
controlFlowObfuscation = true
referenceProxy = true
antiDebug = true
antiTamper = true
resourceProtection = true
}Add runtime protections last. These are the most likely to cause issues during development (anti-debug blocks Android Studio, anti-tamper fails on modified debug APKs).
Phase 4: Name Obfuscation
protections {
nameObfuscation = true // Only if R8 is disabled
}protections {
nameObfuscation = true // Only if R8 is disabled
}Add name obfuscation only after all other protections are stable. If R8 is enabled, leave this disabled.
Variant Strategy
Always use variant configuration to separate development from production:
shield {
variant('debug') {
protections {
antiDebug = false
antiTamper = false
}
}
variant('release') {
protections {
stringEncryption = true
constantMutation = true
debugRemoval = true
controlFlowObfuscation = true
antiDebug = true
antiTamper = true
referenceProxy = true
resourceProtection = true
}
}
}shield {
variant('debug') {
protections {
antiDebug = false
antiTamper = false
}
}
variant('release') {
protections {
stringEncryption = true
constantMutation = true
debugRemoval = true
controlFlowObfuscation = true
antiDebug = true
antiTamper = true
referenceProxy = true
resourceProtection = true
}
}
}This lets you develop without Shield-related friction while ensuring releases are fully protected.
Exclude Aggressively at First
Start with broad exclusions and narrow them as you gain confidence:
excludedPackages = [
'android',
'androidx',
'kotlin',
'kotlinx',
'com.google',
'com.squareup',
'dagger',
'javax.inject',
'io.reactivex',
'org.reactivestreams'
]excludedPackages = [
'android',
'androidx',
'kotlin',
'kotlinx',
'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.
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