Quick Start
This guide walks you through adding Shield to an existing Android project, configuring protections, and verifying the results.
Prerequisites
Before you start, make sure you have:
- An Android project using Gradle (AGP 7.0+ or 8.0+)
- Java 11 or higher
- A ByteHide account with a project token
Step 1: Configure Repositories
Shield is published on Maven Central. Add the standard repositories to your settings.gradle if you don't have them already:
// settings.gradle
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}// settings.gradle
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}Step 2: Apply the Plugin
Add the Shield plugin to your app-level build.gradle:
// app/build.gradle
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'com.bytehide.shield' version '1.0.0'
}// app/build.gradle
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'com.bytehide.shield' version '1.0.0'
}Step 3: Add the Runtime Dependency
Shield requires a lightweight runtime library for string decryption at runtime:
dependencies {
implementation 'com.bytehide:shield-java-runtime:1.0.0'
}dependencies {
implementation 'com.bytehide:shield-java-runtime:1.0.0'
}Step 4: Configure Protections
Add the shield block to your build.gradle. Start with a safe baseline configuration:
shield {
projectToken = "your-project-token"
protections {
stringEncryption = true
constantMutation = true
debugRemoval = true
}
excludedPackages = [
'android',
'androidx',
'kotlin',
'kotlinx'
]
verbose = true
}shield {
projectToken = "your-project-token"
protections {
stringEncryption = true
constantMutation = true
debugRemoval = true
}
excludedPackages = [
'android',
'androidx',
'kotlin',
'kotlinx'
]
verbose = true
}This configuration encrypts all string literals, transforms numeric constants, and removes debug metadata. The verbose = true flag prints detailed output during the build so you can see what Shield is doing.
Step 5: Build
Run a release build:
./gradlew assembleRelease./gradlew assembleReleaseWith verbose = true, you will see Shield's output in the build log:
> Task :app:shieldTransformRelease
Shield: Processing 142 classes...
Shield: String encryption: 847 strings encrypted
Shield: Constant mutation: 1,203 constants transformed
Shield: Debug removal: 142 classes cleaned
Shield: Protection complete in 3.2s> Task :app:shieldTransformRelease
Shield: Processing 142 classes...
Shield: String encryption: 847 strings encrypted
Shield: Constant mutation: 1,203 constants transformed
Shield: Debug removal: 142 classes cleaned
Shield: Protection complete in 3.2sStep 6: Verify
To confirm your APK is protected, decompile it with JADX and compare:
Before Shield:
public class ApiClient {
private static final String API_KEY = "sk_live_abc123def456";
private static final String BASE_URL = "https://api.example.com/v2";
public Response fetchUser(int userId) {
return httpGet(BASE_URL + "/users/" + userId);
}
}public class ApiClient {
private static final String API_KEY = "sk_live_abc123def456";
private static final String BASE_URL = "https://api.example.com/v2";
public Response fetchUser(int userId) {
return httpGet(BASE_URL + "/users/" + userId);
}
}After Shield:
public class a {
private static final String b = StringDecryptor.decrypt("\u0012\u0045\u0078...", "xK", 42, true);
private static final String c = StringDecryptor.decrypt("\u0033\u0067\u0021...", "mQ", 17, false);
public Response a(int i) {
return a(StringDecryptor.decrypt("\u0055\u0012...", "rT", 8, true) + i);
}
}public class a {
private static final String b = StringDecryptor.decrypt("\u0012\u0045\u0078...", "xK", 42, true);
private static final String c = StringDecryptor.decrypt("\u0033\u0067\u0021...", "mQ", 17, false);
public Response a(int i) {
return a(StringDecryptor.decrypt("\u0055\u0012...", "rT", 8, true) + i);
}
}Strings are encrypted, class and method names are obfuscated, and constants are transformed.
Next Steps
Once your base configuration works:
- Add more protections — Enable
nameObfuscation,controlFlowObfuscation, andantiDebugfor stronger protection. See Protections for the full list. - Configure per variant — Use different protection levels for debug and release builds. See Variant Configuration.
- Fine-tune exclusions — Use annotations to exclude specific classes from protection if you encounter issues with reflection or serialization.
- Set up CI/CD — Automate protected builds in your pipeline. See CI/CD Integration.