/

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

Kotlin
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

Kotlin
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

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

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

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

  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