/

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

Groovy
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

Groovy
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

Groovy
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

Groovy
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:

Groovy
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:

Groovy
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:

  1. Run your test suite against the protected APK, not just the unprotected one
  2. Test on real devices — emulators may trigger anti-debug detection
  3. Test serialization — Verify JSON parsing, database operations, and API calls
  4. Test deep links and intents — These rely on class names in the manifest
  5. 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:

Groovy
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

Previous
Troubleshooting