| name | android-apk-patch | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| description | A complete, self-contained reference for modifying Android APKs — from decompilation to adding features, signing, testing, and local delivery. Covers split APKs, GApps, signing schemes, and dynamic analysis. No Xposed/LSPatch dependency. | |||||||||||
| metadata |
|
- Toolchain Setup & Version Requirements
- Decompilation & Recompilation Workflow
- Split APK Handling (.apks / .apkm / .xapk)
- Signing: Schemes, Pitfalls, and Fix Procedures
- Dependency Hell: Frameworks, AndroidX, OEM Resources
- GApps-Dependent APKs: Patching & Workarounds
- Testing Without a Physical Device
- Local Testing: Redroid & Waydroid
- Advanced Patching Techniques → references/advanced-patching.md
- Adding Features to an APK → references/adding-features.md
- Delivering the APK to an End User → references/delivery.md
- End-to-End Workflow: Zero to Delivery → references/end-to-end-workflow.md
- Troubleshooting: Common Failures & Resolutions → references/troubleshooting.md
- Quick Reference Cheat Sheet → references/quick-reference.md
| Tool | Version | Purpose | URL |
|---|---|---|---|
| Apktool | v2.11.0 (Jan 2025) | Decompile/recompile APKs | https://github.com/iBotPeaches/Apktool |
| jadx | v1.5.1 | Read-only Java decompiler | https://github.com/skylot/jadx |
| smali/baksmali | v3.0.9 (bundled in Apktool 2.11.0) | DEX bytecode assembly/disassembly | https://github.com/baksmali/smali |
| APKEditor | Latest | Merge/split APK handling | https://github.com/pxb1988/APKEditor |
| apksigner | SDK Build Tools 35.0.x | APK signing (v1/v2/v3/v4) | Part of Android SDK |
| zipalign | SDK Build Tools 35.0.x | APK alignment before signing | Part of Android SDK |
| Frida | v17.9.0 | Dynamic instrumentation | https://frida.re |
| ADB | Platform Tools 35.0.x | Device/emulator communication | Part of Android SDK |
- Apktool < 2.9.0 — Cannot handle API 34+ resources. Decompilation of Android 14+ APKs will crash with obscure AAPT errors or produce corrupted
resources.arscoutput. - Apktool < 2.6.0 — Uses legacy AAPT (v1) instead of AAPT2. Causes massive resource recompilation failures with any app using AndroidX, Material Components, or modern resource features.
- smali < 3.0.5 — Cannot disassemble DEX format 038+ (Android 13+). baksmali will fail with
"Unsupported DEX format"on any app compiled withminSdkVersion 33+. - jarsigner (any version) — Only produces v1 (JAR) signatures. Modern Android (7.0+) requires at minimum v2 signatures. Using jarsigner will result in
INSTALL_PARSE_FAILED_NO_CERTIFICATESor silent signature rejection.
# Java 11+ required (Java 17 recommended)
java -version # verify
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
# Install Apktool
# Download latest from https://github.com/iBotPeaches/Apktool/releases
# Move apktool.jar to PATH
chmod +x apktool
sudo mv apktool /usr/local/bin/
# Install Android SDK Build Tools (for apksigner + zipalign)
sdkmanager "build-tools;35.0.0"
sdkmanager "platform-tools"
# Install jadx
# Download from https://github.com/skylot/jadx/releases
# Extract and add bin/ to PATH
# Install Frida
pip install frida-tools
# Install APKEditor
# Download APKEditor.jar from https://github.com/pxb1988/APKEditor/releases# Step 1: Analyze with jadx first (understand what you're modifying)
jadx-gui target.apk # GUI for exploration
# or
jadx -d analysis_output/ target.apk # CLI
# Step 2: Decompile with apktool
apktool d target.apk -o decompiled/ -f
# -f = force overwrite existing output directory
# --api 35 = force target API level (use if resource errors occur)
# Step 3: Make modifications
# - Edit smali files in decompiled/smali*/ (Java bytecode)
# - Edit resources in decompiled/res/ (layouts, strings, drawables)
# - Edit AndroidManifest.xml (permissions, components)
# - Edit assets/ (bundled files, web content)
# Step 4: Recompile
apktool b decompiled/ -o rebuilt.apk
# Use --use-aapt2 flag if not on 2.11.0 (now default)
# Step 5: Align (CRITICAL - must be BEFORE signing)
zipalign -v -p 4 rebuilt.apk rebuilt_aligned.apk
# Step 6: Sign
apksigner sign --ks ~/.android/debug.keystore \
--ks-pass pass:android \
--key-pass pass:android \
rebuilt_aligned.apk
# Step 7: Verify
apksigner verify --verbose --print-certs rebuilt_aligned.apk
# Step 8: Install
adb install -r rebuilt_aligned.apk# Force specific API level (fixes many resource resolution issues)
apktool d target.apk -o out/ -f --api 35
# Ignore missing resources (new in 2.11.x, for XAPK/base APK decompilation)
apktool d target.apk -o out/ -f --ignore-missing-resources
# Keep original sources only (skip resources, faster)
apktool d target.apk -o out/ -f -s
# Decode only resources (skip smali, for resource-only mods)
apktool d target.apk -o out/ -f -r
# For Samsung/Android 15 framework JARs with DEX format 039
apktool d framework.jar -api 29 -o out/
# Use a custom framework file (for OEM system APKs)
apktool if /path/to/oem-framework.apk
apktool d system_app.apk -o out/ -fdecompiled/
├── AndroidManifest.xml # App manifest (XML format, editable)
├── apktool.yml # Apktool metadata (DO NOT manually edit version fields)
├── assets/ # Raw asset files
├── lib/ # Native libraries (.so files) by architecture
│ ├── arm64-v8a/
│ ├── armeabi-v7a/
│ └── x86_64/
├── original/ # Original files (META-INF, etc.)
├── res/ # Compiled resources (XML format, editable)
│ ├── values/ # String values, styles, colors, dimensions
│ ├── layout/ # Layout XML files
│ ├── drawable/ # Vector drawables, layer lists
│ ├── xml/ # Preferences, searchable config, etc.
│ └── mipmap-*/ # App icons by density
├── smali/ # Disassembled DEX bytecode (MAIN CODE)
│ ├── com/
│ │ └── example/
│ │ └── app/
│ │ ├── MainActivity.smali
│ │ └── ...
│ └── android/
│ └── ...
└── smali_classes2/ # Additional DEX files (multi-dex apps)
└── ...
Smali is a human-readable representation of DEX bytecode. Key patterns you'll encounter:
# Class declaration
.class public Lcom/example/app/MainActivity;
.super Landroidx/appcompat/app/AppCompatActivity;
# Method declaration
.method public onCreate(Landroid/os/Bundle;)V
.registers 4
# Calling super
invoke-super {p0, p1}, Landroidx/appcompat/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V
# Setting a field
const-string v0, "patched_value"
iput-object v0, p0, Lcom/example/app/MainActivity;->mStatus:Ljava/lang/String;
# Conditional check
if-eqz v0, :cond_skip
# ... code ...
:cond_skip
return-void
.end method
# Common patches:
# 1. Force a boolean method to always return true
.method public isPremium()Z
.registers 2
const/4 v0, 0x1 # true
return v0
.end method
# 2. NOP out a method call (comment effect by replacing with nop)
# Replace: invoke-virtual {v0}, Lcom/example/Payroll;->show()V
# With: nop
# 3. Remove a permission check
# Replace: if-eqz v0, :cond_deny
# With: nop # always falls throughResources are stored as compiled XML (AXML) that apktool decodes. Common modifications:
<!-- res/values/strings.xml - Change app name -->
<string name="app_name">My Patched App</string>
<!-- res/values/colors.xml - Change theme colors -->
<color name="primary">#FF6200EE</color>
<!-- AndroidManifest.xml - Add permissions -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<!-- AndroidManifest.xml - Export an activity (make it launchable) -->
<activity android:name=".HiddenActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- res/layout/activity_main.xml - Modify UI -->
<TextView
android:id="@+id/status_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PATCHED" />Modern Play Store apps use Android App Bundles (AAB), which are split into multiple APKs:
| Format | Source | Extension | Contents |
|---|---|---|---|
| Bundletool | Google Play / developer tools | .apks |
ZIP with base + splits + toc.pb (protobuf metadata) |
| APKMirror | APKMirror downloads | .apkm |
Same as .apks, renamed |
| APKPure | APKPure downloads | .xapk |
Similar concept, slightly different metadata |
| Individual | Manual extraction | .apk each |
Each split as separate APK file |
Split types you'll encounter:
base.apk— Core app code, shared resources, manifestsplit_config.arm64_v8a.apk— ARM64 native librariessplit_config.armeabi_v7a.apk— ARMv7 native librariessplit_config.x86_64.apk— x86_64 native librariessplit_config.xxhdpi.apk— Screen density-specific resourcessplit_config.en.apk— Language-specific resourcessplit_config.google_apis.apk— Google APIs integration codesplit_config.firebase.apk— Firebase integration code
# Step 1: Extract splits from bundle format
# .apks and .apkm are just ZIP files
mkdir splits/ && cd splits/
unzip ../input.apks # or .apkm
# This produces: base.apk, split_config.*.apk, toc.pb, etc.
# For .xapk, same approach:
unzip ../input.xapk
# Step 2: Merge into a single "fat APK" using APKEditor
java -jar APKEditor.jar m -i base.apk split_config.arm64_v8a.apk \
split_config.xxhdpi.apk split_config.en.apk -o merged.apk
# APKEditor intelligently merges resource tables from all splits.
# The resulting merged.apk is self-contained for decompilation.
# Step 3: Decompile the merged APK
apktool d merged.apk -o decompiled/ -f
# Step 4: Make your modifications (smali, resources, manifest)
# Step 5: Recompile
apktool b decompiled/ -o modified_base.apk
# Step 6: Align and sign (see Section 4)
zipalign -v -p 4 modified_base.apk modified_base_aligned.apk
apksigner sign --ks ~/.android/debug.keystore \
--ks-pass pass:android --key-pass pass:android \
modified_base_aligned.apkOption A: Replace base APK only (recommended when possible)
If you only modified the base APK (most common scenario), you can keep the original split APKs:
# Uninstall the app first (signature mismatch will block update)
adb uninstall com.example.app
# Install base + original splits together
adb install-multiple modified_base_aligned.apk \
splits/split_config.arm64_v8a.apk \
splits/split_config.xxhdpi.apk \
splits/split_config.en.apkOption B: Re-sign ALL APKs with the same key
If splits fail because of signature mismatch (some splits embed signature checks):
# Sign every APK with the same keystore
for apk in modified_base_aligned.apk splits/split_config.*.apk; do
apksigner sign --ks ~/.android/debug.keystore \
--ks-pass pass:android --key-pass pass:android \
"$apk"
done
# Install all at once
adb install-multiple modified_base_aligned.apk splits/split_config.*.apkOption C: Create a new bundle for distribution
# Create .apks bundle using bundletool
java -jar bundletool.jar build-bundle \
--modules=modified_base_aligned.apk,splits/split_config.arm64_v8a_apk \
--output=patched.apks| Pitfall | Description | Fix |
|---|---|---|
| Missing native libs after merge | APKEditor may not merge all lib/ directories from arch splits |
Manually copy missing .so files into merged APK's lib/ before decompiling |
| Resource conflicts during merge | Two splits define same resource ID with different values | Merge only base + arch split first, then add density/language splits one at a time |
toc.pb metadata mismatch |
Modified APK doesn't match original bundle metadata | Don't use bundletool for installation — use adb install-multiple directly |
| Feature module splits | Some splits contain code (not just resources) | Decompile the feature split separately, understand its code, and merge smali directories |
Base APK decompilation produces null resources |
Known apktool issue with some split APK bases | Merge with APKEditor first, or use --ignore-missing-resources flag |
| Scheme | Since | Mechanism | Tamper Resistance |
|---|---|---|---|
| v1 (JAR signing) | API 1 (all Android) | Signs individual file entries inside META-INF/ |
Weak — can strip and re-sign without app knowing |
| v2 (APK Signature Scheme v2) | API 24 (Android 7.0) | Binary signature block before ZIP central directory; verifies entire APK | Strong — any byte modification (even metadata) invalidates it |
| v3 (APK Signature Scheme v3) | API 28 (Android 9.0) | Same as v2 + supports key rotation via proof-of-rotation lineage | Same integrity + allows changing signing keys |
| v4 (APK Signature Scheme v4) | API 30 (Android 11) | Merkle hash tree stored separately; enables streaming verification during incremental installs | Same integrity + incremental install support |
Critical rule: v2/v3 are whole-APK signatures. Modifying even a single byte of smali code, a single resource string, or even the ZIP comment field invalidates them. This is why every recompilation requires a full re-sign.
Android verification order: v4 → v3 → v2 → v1 (falls back through each level).
| Feature | apksigner | jarsigner |
|---|---|---|
| Signature schemes | v1, v2, v3, v4 | v1 only |
| Whole-APK verification | Yes | No |
| Key rotation support | Yes (v3) | No |
| Required for API 24+ | Yes | No — will be rejected |
| Alignment awareness | Yes | No |
| Source | Android SDK Build Tools | JDK |
NEVER use jarsigner for APK signing. Period. It produces v1-only signatures that modern Android (7.0+) silently rejects or explicitly denies installation.
# === Creating a Custom Keystore (one-time) ===
keytool -genkey -v -keystore ~/release.keystore \
-alias myapp \
-keyalg RSA \
-keysize 2048 \
-validity 10000
# You'll be prompted for:
# - Keystore password (use something STRONG and memorable)
# - Key password (same or different)
# - Your name, organization, city, state, country code
# Store the keystore and passwords securely — you CANNOT change the key later
# === Using the Android Debug Keystore (for testing only) ===
# Location: ~/.android/debug.keystore
# Password: android
# Alias: androiddebugkey
# This keystore is identical on ALL Android SDK installations.
# DO NOT use for production — apps signed with it cannot be published or updated.
# === Full Signing Workflow ===
# Step 1: Align the APK (MUST be before signing)
zipalign -v -p 4 rebuilt.apk rebuilt_aligned.apk
# Step 2: Sign with apksigner (all three schemes for maximum compatibility)
apksigner sign \
--ks ~/release.keystore \
--ks-key-alias myapp \
--ks-pass pass:your_keystore_password \
--key-pass pass:your_key_password \
--v1-signing-enabled true \
--v2-signing-enabled true \
--v3-signing-enabled true \
rebuilt_aligned.apk
# Note: v4 is NOT signed here — it's computed on-demand during installation
# Step 3: Verify the signature
apksigner verify --verbose --print-certs rebuilt_aligned.apk
# Expected output:
# Verifies
# Verified using v1 scheme (JAR signing): true
# Verified using v2 scheme (APK Signature Scheme v2): true
# Verified using v3 scheme (APK Signature Scheme v3): true
# Number of signers: 1
# Step 4: Optional — Check what schemes are present
apksigner verify --print-certs -v rebuilt_aligned.apk| Error Message | Root Cause | Fix |
|---|---|---|
INSTALL_FAILED_UPDATE_INCOMPATIBLE |
App already installed with different signing key | adb uninstall com.example.app then reinstall |
INSTALL_PARSE_FAILED_NO_CERTIFICATES |
APK not signed at all | Sign with apksigner |
INSTALL_FAILED_VERIFICATION_FAILURE |
Device requires verified installs (MIUI, Samsung Knox) | Disable MIUI optimization, or enable "Install via USB" in Developer Options |
| App installs but immediately crashes | Runtime signature self-check (PackageManager.getPackageInfo() with GET_SIGNATURES) |
See Section 9.3 (Frida signature bypass) or patch smali signature check |
SecurityException: Signature not valid |
App explicitly checks caller signature | Patch the smali signature check, or use signature spoofing (see 6.4) |
INSTALL_FAILED_INVALID_APK |
APK corrupted or malformed after recompilation | Check for AAPT2 errors during build, verify zip integrity |
| Play Store says "App not installed" | Custom signature not recognized by Play Store | Expected — Play Store only accepts Google-signed updates for apps it manages |
Splits fail with INSTALL_FAILED_SESSION_INVALID |
Splits signed with different keys | Sign ALL splits with the same keystore before install-multiple |
If you need to change signing keys (e.g., you lost your keystore):
# Sign with the NEW key, providing the OLD key's lineage
apksigner sign \
--ks new-release.keystore \
--ks-key-alias newkey \
--ks-pass pass:new_password \
--v1-signing-enabled true \
--v2-signing-enabled true \
--v3-signing-enabled true \
--lineage /path/to/lineage-file \
rebuilt_aligned.apk
# To extract lineage from the OLD keystore:
apksigner sign \
--ks old-release.keystore \
--ks-key-alias oldkey \
--ks-pass pass:old_password \
--v3-signing-enabled true \
--lineage /path/to/lineage-file \
--next-signer new-release.keystore newkey pass:new_password \
dummy.apkCaveat: Key rotation only works if the app was PREVIOUSLY signed with v3. If the original app only has v1/v2, you're out of luck — you must uninstall and reinstall.
# Error 1: Missing AndroidX resources
error: resource 'com.example:id/material_textinput' not found
# Error 2: Styleable attribute not found
error: style attribute 'attr/layout_constraintBaseline_toBaselineOf' not found
# Error 3: AAPT2 crash
ERROR: AAPT2 aapt2(...) exited with code 1
brut.androlib.AndrolibException
# Error 4: Duplicate resource
error: resource 'style/Theme.MaterialComponents' has already been defined
# Error 5: Missing framework resource
error: resource '@android:configui_configFlags' not found
Step 1: Install ROM-specific frameworks
For most third-party apps, Apktool's bundled framework (since 2.5.0) is sufficient. But for system apps, OEM apps, or apps that reference framework resources not in AOSP, you need:
# Install the standard Android framework (usually automatic)
apktool if framework-res.apk
# Pull framework files from a rooted device
adb pull /system/framework/ ./device_frameworks/
# Install OEM-specific frameworks
# Samsung:
apktool if device_frameworks/sec_platform_library.jar
apktool if device_frameworks/com.samsung.device.jar
apktool if device_frameworks/frameworksSamsungSDK.jar
# Xiaomi/MIUI:
apktool if device_frameworks/framework-miui-res.apk
apktool if device_frameworks/MiuiSdk.jar
apktool if device_frameworks/framework-mi.jar
# Huawei:
apktool if device_frameworks/HWExtension.jar
apktool if device_frameworks/hwsdk.jar
# OnePlus/Oplus:
apktool if device_frameworks/oplus-framework.jar
apktool if device_frameworks/oplus-res.apk
# Check what frameworks are currently installed
ls ~/.local/share/apktool/framework/Step 2: Install shared library APKs
Some apps depend on vendor-shared library APKs:
# Find shared library APKs on device
adb shell pm list packages -f | grep shared
adb shell pm list packages -f | grep library
# Pull and install as framework
adb pull /system/app/SomeSharedLib/SomeSharedLib.apk
apktool if SomeSharedLib.apkStep 3: Force API level to resolve resource conflicts
# If resources from newer APIs aren't found
apktool d target.apk -o out/ -f --api 35
# If dealing with legacy frameworks
apktool d target.apk -o out/ -f --api 29Step 4: Use the ignore flag for known non-critical missing resources
# New in Apktool 2.11.x
apktool d target.apk -o out/ -f --ignore-missing-resourcesIssue A: Cross-library resource references
AndroidX migrated all android.support.* classes to androidx.* namespaces. This causes two major categories of issues:
- Cross-library resource references: AndroidX libraries reference resources across package boundaries. When decompiled, these may resolve incorrectly.
- R8-obfuscated resource names: When R8 shrinks an app, it may remove unused AndroidX resources. On recompilation, the remaining code may reference resources that were stripped.
Fix: Ensure Apktool 2.11.0+ is used (correctly handles AndroidX cross-references). For R8-obfuscated apps, manually add the required library .aar files as frameworks.
Issue B: Obfuscation
R8/ProGuard/DexGuard can strip resources. This is extremely hard to resolve automatically—your best options are:
- Decompile the original APK without modification and immediately recompile (if that fails too, it's a tool limitation)
- Manually add the missing resource definition to
res/values/files - Use
--ignore-missing-resourcesand accept that some features may break
| Error | Cause | Fix |
|---|---|---|
resource has already been defined |
Duplicate resource entry in AAPT2 | Apktool 2.11.0+ handles most cases. If persists, search for duplicate definitions in res/values/*.xml |
failed to compile values files |
Style/attr references to undefined resources | Check attrs.xml, styles.xml, themes.xml for references to removed resources |
malformed compiled jar |
Samsung DEX format 039 in framework | apktool d -api 29 |
no resource identifier found for attribute |
Missing library dependency | Install the required library APK as framework |
invalid file path |
Windows path length limit or special characters in resources | Move project to short path, rename files |
unmarshalling resource table |
Corrupted resources.arsc in original APK |
Try --ignore-missing-resources, or use APKEditor to decompile instead |
Error: java.nio.BufferOverflowException |
Very large resource table (>2GB) | Use 64-bit Java and increase heap: JAVA_OPTS="-Xmx4g" apktool b ... |
Apps that depend on Google Play Services are the hardest to patch because:
- Split APK hell: Play Services is distributed as ~100+ dynamic feature modules via split APKs
- Runtime signature verification: Both the OS and other GApps verify Play Services' signature at runtime
- DroidGuard attestation: Google's attestation service is deeply integrated into Play Services core
- Automatic updates: The Play Store auto-updates Play Services, overwriting any patches
- Play Integrity API: Modern apps use Play Integrity to verify device and app integrity — impossible to fully bypass on emulators
Bottom line: Do NOT try to directly patch com.google.android.gms. It's a losing battle. Instead, use the approaches in the following sections.
MicroG is a lightweight, open-source replacement for Google Play Services.
# MicroG provides:
# - Location services (via UnifiedNlp / OpenStreetMap backends)
# - Push notifications (via ntfy or custom push servers)
# - Device registration
# - Maps API (via OpenStreetMap)
# - Limited Google account support
# MicroG does NOT provide:
# - Play Integrity passing
# - Full DroidGuard attestation
# - SafetyNet compatibility
# - All Google API parity
# - Some Play Games features
# Setup MicroG:
# 1. Download GmsCore.apk from https://github.com/microg/GmsCore/releases
# Or use "MicroG RE" (Redesign for ReVanced) for better compatibility
# 2. Install on your device/emulator
# 3. Install a push notification provider (e.g., ntfy)
# 4. Configure signature spoofing (see 6.4)ReVanced (the successor to Vanced) provides pre-made patches:
- https://github.com/ReVanced/revanced-patches
- Patches for: YouTube, YouTube Music, Google Photos, etc.
- Handles signature bypass, ad removal, background play, etc.
Manual patching of GApps:
The key challenge: GApps perform runtime signature verification. They check their own signature against a known Google certificate fingerprint and refuse to function if the signature doesn't match.
# The patching approach:
# 1. Decompile the app
apktool d google_app.apk -o decompiled/
# 2. Find the signature verification code
# Search smali for these patterns:
# getPackageInfo
# GET_SIGNATURES
# PackageManager
# MessageDigest
# equals (for signature comparison)
# toByteArray (for signature byte extraction)
# 3. Patch or NOP the signature check
# Common pattern in smali:
# const-string v0, "308203e3..."
# invoke-virtual {v0}, Ljava/lang/String;->getBytes()[B
# invoke-static {...}, Ljava/security/MessageDigest;->getInstance(...)L...
# # Replace with: const/4 v_result, 0x1 (return true/valid)What it does: Makes MicroG's signature appear as the real Google Play Services signature to other apps.
ROM-level support (cleanest approach):
- LineageOS: Settings → System → Developer options → "Allow signature spoofing"
- AXP.OS, /e/OS, CalyxOS: Built-in with per-app control
Magisk module approach (for stock ROMs):
- Patches
framework.jarat runtime to allow apps to declare spoofing support - MicroG declares spoofing support in its manifest
- Other apps query MicroG's signature and receive Google's signature bytes
# Install signature spoofing Magisk module:
# Search for "FakeGApps" or "sigspoof" in Magisk Modules repository
# Or use: https://github.com/microg/android_packages_apps_GmsCore/wiki/Installation| Tool | Type | Works On | Status |
|---|---|---|---|
| TrickyStore | Magisk module | Android 8+ (with Zygisk) | Active — spoofs device attestation key |
| Play Integrity Fix NEXT | Magisk module | Android 8+ (with Zygisk) | Active — aims for valid attestation |
| PIFork | Magisk module | Pre-Android 13 | Active fork by osm0sis |
Stack for passing Play Integrity (2025):
- Root via Magisk / KernelSU / APatch
- Install ZygiskNext
- Install Play Integrity Fix (or NEXT/fork)
- Install TrickyStore + TrickyStore Addon
- Do NOT put
com.google.android.gmson Magisk DenyList
CRITICAL LIMITATION: Play Integrity does NOT pass on any emulator. Emulators are detected via hardware attestation checks that cannot be spoofed in software. For Play Integrity testing, you MUST use a physical device.
| Emulator | Root Support | ARM Translation | GApps Support | Best For | Verdict |
|---|---|---|---|---|---|
| Android Studio AVD | Magisk via rootAVD | Native (ARM images) / Translated (x86) | Google APIs / Google Play images | Dev, security testing, patch verification | Best choice |
| Genymotion | Built-in basic root | libhoudini (not included by default since 3.x) | Requires manual GApps flash | Professional CI/CD testing | Good for automated testing |
| Waydroid | Magisk via script | libndk_translation (SSE 4.2 required) | Manual via waydroid_script | Linux desktop Android apps | Good for Linux users |
| BlueStacks | Difficult, no Magisk | Built-in | Pre-installed | Gaming only | Not recommended for dev work |
| Nox | Clunky, unreliable | Built-in | Partial | Gaming/automation | Not recommended for dev work |
# Step 1: Install Android Studio
# Download from https://developer.android.com/studio
# Step 2: Create an AVD (Virtual Device)
# Android Studio → Tools → Device Manager → Create Device
# Recommended configuration:
# - Device: Pixel 7 (or any recent phone profile)
# - System Image: API 35 (Android 15), x86_64 (for speed)
# OR ARM64 if testing ARM-specific native libs
# - RAM: 4096 MB minimum (8192 MB preferred)
# - AVD Name: "test_device_api35"
# Step 3: Root the AVD with rootAVD
pip3 install rootAVD
rootAVD -s test_device_api35 # Root by AVD name
# Step 4: Verify root
emulator -avd test_device_api35 -no-snapshot-load
adb shell su -c "id"
# Expected: uid=0(root) gid=0(root)
# Step 5: Install Magisk modules (if needed)
# Push module zip to device and flash via Magisk app
adb push module.zip /sdcard/Download/
# Then flash in Magisk Manager app on the emulator
# Step 6: Install your patched APK
adb install -r patched.apk
# For split APKs:
adb install-multiple base.apk split_config.arm64_v8a.apk split_config.en.apk
# Force downgrade if version conflict:
adb install -r -d -t patched.apk
# Clean install if signature mismatch:
adb uninstall com.example.app
adb install patched.apkOption A: AVD with Google APIs image
# Create AVD with "Google APIs" system image
# Android Studio → Device Manager → Create Device
# Choose system image: "Google APIs" (not "Google Play")
# This includes Play Services but allows more flexibility
# Caveat: Pre-installed Google Play Services CANNOT be replaced
# with patched versions because the system expects Google's signatureOption B: AVD without Google APIs + MicroG (recommended for GApps-free testing)
# Create AVD with "No Google APIs" / AOSP system image
# This gives you a clean slate
# Install MicroG:
adb install GmsCore.apk
adb install ntfy.apk # Push notification provider
# Install your patched app:
adb install patched.apk
# Verify MicroG self-check:
# Open MicroG app → Self-check → All should be green (except Play Integrity)Android Studio AVD:
- x86_64 images: ~10x faster than ARM emulation. Uses native x86 execution.
- ARM64 images: Slower but runs ARM native libraries directly.
- ARM translation: When running x86_64 image with ARM APKs, the emulator translates ARM instructions to x86 transparently.
- Problem: Some native libraries (anti-tamper, anti-debug, DRM) detect the translation layer and refuse to run.
- Fix: Use ARM64 system images when testing apps with ARM-specific native code that performs translation detection.
Genymotion:
- Runs x86 images by default
- libhoudini for ARM translation (not included since Genymotion 3.x)
- Install via: https://github.com/vnsh01/Nyx (for Android 11)
- macOS Apple Silicon devices don't need translation (native ARM64)
Waydroid:
- Uses host Linux kernel directly (container, not emulation)
- ARM translation via libndk_translation
- Requires SSE 4.2 CPU instructions
- Install via waydroid_script: https://github.com/casualsnek/waydroid_script
# Install Frida tools
pip install frida-tools
# Download frida-server for the emulator's architecture
# Check architecture: adb shell getprop ro.product.cpu.abi
# For x86_64 emulator: download frida-server-x86_64.xz
# For arm64 emulator: download frida-server-arm64.xz
# Push and run frida-server
adb push frida-server /data/local/tmp/
adb shell "chmod 755 /data/local/tmp/frida-server"
adb shell "/data/local/tmp/frida-server -D &"
# Verify connection
frida-ps -U # Should list running processes
# Run Frida REPL against a running app
frida -U -n com.example.app
# Spawn app with Frida injected
frida -U -f com.example.app -l hook.js --no-pause
# Run a JavaScript hook script
frida -U -l bypass_signature.js -n com.example.app# === Installation ===
adb install -r app.apk # Replace existing app
adb install -d app.apk # Allow version downgrade
adb install -t app.apk # Allow test APKs
adb install-multiple base.apk s1.apk s2.apk # Split APKs
adb uninstall com.example.app # Remove app + data
# === Debugging ===
adb logcat # View logs
adb logcat -s "ActivityManager" # Filter by tag
adb logcat | grep -i "FATAL" # Filter crash logs
adb shell dumpsys package com.example.app # Package info
# === File operations ===
adb push file.txt /sdcard/ # Upload file
adb pull /sdcard/file.txt ./ # Download file
# === Root operations ===
adb shell su -c "command" # Run as root
adb shell su -c "mount -o rw,remount /system"
adb push patched.apk /system/app/TargetApp/target.apk
adb shell su -c "chmod 644 /system/app/TargetApp/target.apk"
# === Emulator-specific ===
emulator -avd NAME -no-snapshot-load # Start emulator fresh
adb reboot # Reboot emulator| Flag | Meaning | Use Case |
|---|---|---|
-r |
Replace/reinstall existing app | Updating a patched APK |
-d |
Allow version downgrade | Installing older patched version |
-t |
Allow test APKs (android:testOnly="true") |
Debug/test builds |
-g |
Grant all runtime permissions | Testing with all permissions |
--force-install |
Force install (Android 13+) | Bypass signature/version checks |
-p |
Partial install (split APK mode) | Internal use for install-multiple |
Location: ~/.android/debug.keystore
Password: android
Alias: androiddebugkey
Key pass: android
When to use: Local-only testing on redroid, Waydroid, your own devices, emulators.
When NOT to use: Distributing APKs to others, publishing to Play Store.
# One-time creation
keytool -genkey -v \
-keystore ~/apk-testing.keystore \
-alias testing \
-keyalg RSA \
-keysize 2048 \
-validity 10000
# You'll be prompted for:
# - Keystore password (use something STRONG and memorable)
# - Key password (same or different)
# - Your name, organization, city, state, country code
#
# BACKUP THIS FILE. If you lose it, you'll have to uninstall and reinstall every app you ever signed.# CORRECT ORDER:
zipalign -v -p 4 rebuilt.apk rebuilt_aligned.apk # Step 1: ALIGN first
apksigner sign --ks key.keystore aligned.apk # Step 2: SIGN second
# WRONG ORDER (will break v2/v3 signatures):
apksigner sign --ks key.keystore rebuilt.apk # Signing first
zipalign -v -p 4 rebuilt.apk aligned.apk # Then aligning BREAKS the signature!Why: v2/v3 signatures are computed over the entire APK binary, including the position of entries within the ZIP. zipalign moves entries around to 4-byte boundaries, which invalidates any signature computed before alignment.
When testing split APKs on redroid/Waydroid, ALL splits in a bundle must share the same signing key:
# Extract splits from .apks/.apkm
unzip input.apks -d splits/
# Align all APKs
for apk in splits/*.apk; do
zipalign -v -p 4 "$apk" "${apk%.apk}_aligned.apk"
done
# Sign ALL splits with THE SAME key
for apk in splits/*_aligned.apk; do
apksigner sign \
--ks ~/apk-testing.keystore \
--ks-key-alias testing \
--ks-pass pass:your_password \
--key-pass pass:your_password \
"$apk"
done
# Install all at once via ADB
adb install-multiple splits/base_aligned.apk \
splits/split_config.arm64_v8a_aligned.apk \
splits/split_config.en_aligned.apkIf you want to skip the manual zipalign + apksigner dance:
# Download from https://github.com/patrickfav/uber-apk-signer/releases
java -jar uber-apk-signer.jar --apks rebuilt.apk
# Handles: zipalign + sign with debug keystore + verify
# Output: rebuilt-aligned-debugSigned.apk
# With custom keystore
java -jar uber-apk-signer.jar \
--apks rebuilt.apk \
--ks ~/apk-testing.keystore \
--ksAlias testing \
--ksPass your_password
# Sign multiple APKs at once (splits)
java -jar uber-apk-signer.jar --apks splits/| Mistake | What Happens | Fix |
|---|---|---|
| zipalign AFTER sign | INSTALL_FAILED_VERIFICATION |
Always zipalign first |
| Used jarsigner instead of apksigner | v2/v3 signatures missing; Android 7.0+ rejects | Use apksigner |
| Split APKs signed with different keys | INSTALL_FAILED_SESSION_INVALID |
Sign ALL with same keystore |
| Modified APK after signing | Signature broken | Never modify post-sign |
| Wrong keystore password | Keystore was tampered with, or password was incorrect |
Verify with keytool -list |
| Not aligned at all | App installs but runs slow; INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION on some ROMs |
Always run zipalign -v -p 4 |
| Missing v2 scheme on API 24+ | Silent rejection or INSTALL_PARSE_FAILED_NO_CERTIFICATES |
apksigner defaults to v1+v2; verify with apksigner verify -v |
Redroid (Remote-android) runs a full Android system inside a Docker container. It does NOT use QEMU or virtualization — it runs Android userspace natively on the host Linux kernel using LXC primitives.
Key characteristics:
- Runs as a Docker container — fully containerized, reproducible, scriptable
- Root by default (uid=0 inside the container)
- ADB access via TCP on port 5555
- No display by default (headless) — use scrcpy for screen mirroring if needed
- Supports Android 11 through 15
- Perfect for CI/CD, batch testing, and automated APK validation
Official resources:
- Docs: https://github.com/remote-android/redroid-doc
- Docker Hub: https://hub.docker.com/r/redroid/redroid
- Kernel modules: https://github.com/remote-android/redroid-modules
# 1. Install Docker
sudo apt install docker.io docker-compose
sudo usermod -aG docker $USER # Log out and back in
# 2. Install binder kernel module
sudo apt install linux-modules-extra-$(uname -r)
# 3. Load binder module
sudo modprobe binder_linux
# 4. Verify binder is available
ls /dev/binderfs 2>/dev/null && echo "OK: binderfs found" || echo "MISSING"
# 5. For Android 12+: ashmem is replaced by memfd (no extra module needed)
# For Android 11: also load ashmem
sudo modprobe ashmem_linuxKernel version requirement: 4.14+ (virtually all modern distros satisfy this).
WSL2 support: Possible but requires a custom WSL2 kernel with binder modules. See https://github.com/remote-android/redroid-doc/blob/master/deploy/wsl.md. macOS is NOT directly supported (Docker Desktop on macOS lacks binder).
Minimal headless container (for pure APK install/run testing):
docker run -d \
--privileged \
--name redroid14 \
-p 5555:5555 \
redroid/redroid:14.0.0-latestWith GPU acceleration (Intel/AMD via Mesa/virgl):
docker run -d \
--privileged \
--name redroid14 \
-p 5555:5555 \
-v /dev/dri:/dev/dri \
redroid/redroid:14.0.0-latest \
androidboot.redroid_width=1080 \
androidboot.redroid_height=1920 \
androidboot.redroid_dpi=320With persistent data (apps survive container restart):
docker volume create redroid_data
docker run -d \
--privileged \
--name redroid14 \
-p 5555:5555 \
-v /dev/dri:/dev/dri \
-v redroid_data:/data \
redroid/redroid:14.0.0-latest \
androidboot.redroid_width=1080 \
androidboot.redroid_height=1920 \
androidboot.redroid_dpi=320Docker Compose (recommended for reproducible setups):
# docker-compose.yml
services:
redroid:
image: redroid/redroid:14.0.0-latest
container_name: redroid14
privileged: true
ports:
- "5555:5555"
volumes:
- /dev/dri:/dev/dri
- redroid_data:/data
command:
- "androidboot.redroid_width=1080"
- "androidboot.redroid_height=1920"
- "androidboot.redroid_dpi=320"
volumes:
redroid_data:docker compose up -d # Start
docker compose logs -f # View boot logs (wait for "Boot completed")
docker compose down # Stop| Tag | Android | Notes |
|---|---|---|
redroid/redroid:11.0.0-latest |
11 | Stable, legacy |
redroid/redroid:12.0.0-latest |
12 | Stable |
redroid/redroid:13.0.0-latest |
13 | Stable |
redroid/redroid:14.0.0-latest |
14 | Recommended — most stable |
redroid/redroid:15.0.0-latest |
15 | Newer, check stability |
redroid/redroid:14.0.0_64only-latest |
14 | 64-bit only (smaller, fewer compat issues) |
erstt/redroid |
Various | Pre-built with ARM translation |
# Wait for container to boot (check logs: "Boot completed")
docker logs redroid14 2>&1 | tail -5
# Connect ADB via TCP
adb connect localhost:5555
adb devices
# Expected: localhost:5555 device
# === Install patched APK ===
# Basic install
adb -s localhost:5555 install rebuilt_aligned.apk
# Reinstall over existing
adb -s localhost:5555 install -r rebuilt_aligned.apk
# Force install (bypass version/signature conflicts)
adb -s localhost:5555 install -d -t --force-install rebuilt_aligned.apk
# Install split APKs
adb -s localhost:5555 install-multiple base_aligned.apk \
split_config.arm64_v8a_aligned.apk \
split_config.xxhdpi_aligned.apk
# Grant all runtime permissions
adb -s localhost:5555 install -r -g rebuilt_aligned.apk
# === App management ===
adb -s localhost:5555 shell pm list packages # List all
adb -s localhost:5555 shell pm list packages -3 # Third-party only
adb -s localhost:5555 uninstall com.example.app # Remove
adb -s localhost:5555 shell am force-stop com.example.app # Force stop
adb -s localhost:5555 shell am start -n com.example.app/.MainActivity # Launch
# === Shell access (root by default!) ===
adb -s localhost:5555 shell
whoami # root
id # uid=0(root) gid=0(root)
# === Screen mirroring (if you need to see the UI) ===
# Use scrcpy (install: sudo apt install scrcpy)
scrcpy -s localhost:5555All three can be installed via redroid-script without rebuilding the Docker image:
git clone https://github.com/abing7k/redroid-script.git
cd redroid-script
# Install everything in one go
sudo python3 redroid-script.py redroid14 --gapps --magisk --libndk
# Or individually:
sudo python3 redroid-script.py redroid14 --gapps # OpenGApps
sudo python3 redroid-script.py redroid14 --magisk # Magisk
sudo python3 redroid-script.py redroid14 --libndk # ARM translation (libndk_translation)
sudo python3 redroid-script.py redroid14 --houdini # ARM translation (Intel Houdini)
# Restart container after installation
docker restart redroid14Note: Magisk installation may require 2-3 container restarts to fully initialize, especially with Zygisk enabled.
# === One-time setup ===
sudo modprobe binder_linux
docker volume create redroid_data
docker run -d --privileged --name redroid14 -p 5555:5555 \
-v redroid_data:/data redroid/redroid:14.0.0-latest
# Wait ~30s for boot, then:
adb connect localhost:5555
# === GApps + ARM translation (one-time, optional) ===
git clone https://github.com/abing7k/redroid-script.git
sudo python3 redroid-script.py redroid14 --gapps --libndk
docker restart redroid14
sleep 30
adb connect localhost:5555
# === Per-APK test cycle ===
# 1. Decompile, modify, recompile (see Section 2)
apktool d target.apk -o dec/ -f
# ... make modifications ...
apktool b dec/ -o rebuilt.apk
# 2. Sign
zipalign -v -p 4 rebuilt.apk rebuilt_aligned.apk
apksigner sign --ks ~/apk-testing.keystore \
--ks-key-alias testing --ks-pass pass:your_password \
--key-pass pass:your_password rebuilt_aligned.apk
# 3. Uninstall previous version (if exists)
adb -s localhost:5555 uninstall com.example.app 2>/dev/null
# 4. Install
adb -s localhost:5555 install rebuilt_aligned.apk
# 5. Launch and check logs
adb -s localhost:5555 shell am start -n com.example.app/.MainActivity
adb -s localhost:5555 logcat -s "AndroidRuntime:E" "*:S"
# 6. If needed, mirror screen with scrcpy
scrcpy -s localhost:5555
# === Cleanup ===
docker stop redroid14
docker rm redroid14
docker volume rm redroid_data| Issue | Workaround |
|---|---|
| Container won't start (binder missing) | sudo modprobe binder_linux + linux-modules-extra-$(uname -r) |
| Apps can't access internet | Use --net=host in docker run |
| Long first boot on WSL2 | Store data as Docker volume (not bind mount) |
| ARM app crashes on x86 host | Install ARM translation: redroid-script.py <id> --libndk |
| No audio output | Expected in headless mode; use scrcpy for visual only |
| Magisk instability after install | Restart container 2-3 times |
| GPU artifacts on NVIDIA | Use software rendering (remove -v /dev/dri:/dev/dri) |
Waydroid runs Android as an LXC container with native desktop window integration. Unlike redroid, it displays Android apps as regular windows on your Linux desktop. It requires a Wayland compositor (GNOME Wayland, KDE Plasma Wayland, Sway, Hyprland, etc.).
Key characteristics:
- Android apps appear as native desktop windows
- Clipboard sync between Linux and Android (Wayland only)
- Audio via PulseAudio/PipeWire
- Requires Wayland compositor (or nested weston for X11)
- ADB access via local socket
- Single Android session (not multi-container like redroid)
Official resources:
- Website: https://waydro.id
- Docs: https://docs.waydro.id
- GitHub: https://github.com/waydroid/waydroid
- ArchWiki: https://wiki.archlinux.org/title/Waydroid
# === Ubuntu 22.04 / 24.04 ===
sudo apt install curl ca-certificates
curl https://repo.waydro.id | sudo bash
sudo apt install waydroid
# === Debian ===
curl https://repo.waydro.id | sudo bash
sudo apt install waydroid
# === Arch Linux ===
sudo pacman -S waydroid
# === Fedora ===
sudo dnf install waydroid
# === Initialize (choose one) ===
sudo waydroid init # Vanilla (no Google services)
sudo waydroid init -s GAPS # With OpenGApps (Play Store etc.)
# === Start ===
waydroid session start
waydroid show-full-ui # Opens Android desktop windowcasualsnek/waydroid_script is the Swiss army knife for Waydroid:
git clone https://github.com/casualsnek/waydroid_script.git
cd waydroid_script
sudo pip3 install requests pyyaml # Dependencies
# Install everything:
sudo python3 waydroid_script.py -g -m -l
# -g = GApps (OpenGApps)
# -m = Magisk
# -l = libndk_translation (ARM translation)
# Individual options:
sudo python3 waydroid_script.py -g # GApps only
sudo python3 waydroid_script.py -g --variant pico # GApps, minimal variant
sudo python3 waydroid_script.py -g --microg # MicroG instead of OpenGApps
sudo python3 waydroid_script.py -m # Magisk only
sudo python3 waydroid_script.py -l # libndk_translation
sudo python3 waydroid_script.py -L # libhoudini (alternative ARM translation)
# Restart Waydroid after installation
waydroid session stop
sudo systemctl restart waydroid-container
waydroid session start && waydroid show-full-uiARM translation critical requirement: Your CPU must support SSE 4.2 instruction set:
# Check
cat /proc/cpuinfo | grep sse4_2
# If empty: your CPU doesn't support it — ARM translation won't work# Waydroid exposes ADB via local socket (auto-configured)
adb devices
# Expected: waydroid0 device
# === Install patched APK ===
# Using waydroid CLI (recommended)
waydroid app install /path/to/rebuilt_aligned.apk
# Using ADB directly
adb install /path/to/rebuilt_aligned.apk
adb install -r /path/to/rebuilt_aligned.apk # Reinstall
adb install -d -t --force-install /path/to/app.apk # Force
# Install split APKs via ADB
adb install-multiple base.apk split_config.arm64_v8a.apk
# === App management ===
waydroid app list # List installed packages
waydroid app launch com.example.app # Launch app
waydroid app remove com.example.app # Uninstall
waydroid app list --show-package-name # Show package names
# === Shell access ===
adb shell # Regular shell
sudo waydroid shell # Root shell (if configured)
# === Screen recording / screenshots ===
waydroid ctrl +p # Screenshot (shortcut, if mapped)# === One-time setup ===
curl https://repo.waydro.id | sudo bash
sudo apt install waydroid
sudo waydroid init # or: sudo waydroid init -s GAPS
# Install ARM translation + Magisk
git clone https://github.com/casualsnek/waydroid_script.git
cd waydroid_script
sudo python3 waydroid_script.py -g -m -l
cd ..
waydroid session stop && sudo systemctl restart waydroid-container
waydroid session start && waydroid show-full-ui
# === Per-APK test cycle ===
# 1. Decompile, modify, recompile
apktool d target.apk -o dec/ -f
# ... make modifications ...
apktool b dec/ -o rebuilt.apk
# 2. Sign
zipalign -v -p 4 rebuilt.apk rebuilt_aligned.apk
apksigner sign --ks ~/apk-testing.keystore \
--ks-key-alias testing --ks-pass pass:your_password \
--key-pass pass:your_password rebuilt_aligned.apk
# 3. Uninstall previous version
waydroid app remove com.example.app 2>/dev/null
# 4. Install
waydroid app install rebuilt_aligned.apk
# 5. Launch
waydroid app launch com.example.app
# 6. Check logs
adb logcat -s "AndroidRuntime:E" "*:S"Waydroid relies on Mesa/GBM for GPU rendering. NVIDIA's proprietary driver doesn't use Mesa:
# Workaround 1: Force software rendering
WAYDROID_DISABLE_GPU=1 waydroid session start
# Workaround 2: Switch to integrated GPU (dual-GPU laptops)
# Use prime-select or DRI_PRIME=1
# Workaround 3: NVIDIA open kernel module 575.51.02+
# Recent reports (mid-2025) show Waydroid "works" with open driver
# But GPU acceleration may still be partial| Issue | Workaround |
|---|---|
| NVIDIA GPU: no/flickering rendering | WAYDROID_DISABLE_GPU=1 or switch to iGPU |
| X11: no display | Run nested Wayland: weston & then WAYLAND_DISPLAY=wayland-1 waydroid show-full-ui |
| Camera not working | Very limited support (v4l2 only, no PipeWire) |
| Magisk flaky install | Check waydroid_script version; may need manual Magisk flash |
| Bluetooth/USB not working | Not natively supported |
| Dual GPU flickering | Force iGPU only or use software rendering |
| SELinux blocks Waydroid | Set permissive: sudo setenforce 0 (temp) or configure policy |
→ Full reference: references/advanced-patching.md
This section covers:
- Dynamic instrumentation with Frida (SSL pinning bypass, root detection bypass, signature bypass)
- Dealing with obfuscation (R8/ProGuard/DexGuard)
- Bypassing app integrity checks (file hash verification, tamper detection, DEX integrity, Play Integrity)
- Creating Magisk modules as an alternative to direct patching.
→ Full reference: references/adding-features.md
This section covers:
- Creating new smali classes from scratch
- Adding a new Activity to the app
- Adding external libraries (.jar / .aar)
- Injecting code into the app lifecycle
- Handling multi-DEX when adding code
- Practical example: Adding a "Debug Panel" to any app.
→ Full reference: references/delivery.md
This section covers:
- Release signing (not debug!)
- What the end user must do before installing
- Distribution methods (direct APK, .apks bundle, .apkm, ADB install)
- Preventing Play Store overwrites
- Preparing a user-friendly delivery package.
→ Full reference: references/end-to-end-workflow.md
A complete checklist-driven workflow from toolchain setup to final delivery:
- Phase 1: Setup (one-time)
- Phase 2: Analysis
- Phase 3: Decompile
- Phase 4: Modify
- Phase 5: Recompile & Fix
- Phase 6: Sign & Test (Local)
- Phase 7: Prepare for Delivery
- Phase 8: Deliver
- Phase 9: Maintenance.
→ Full reference: references/troubleshooting.md
Quick reference tables for:
- Decompilation failures
- Recompilation failures
- Installation failures
- Runtime failures (app crashes after install)
- Performance issues.
→ Full reference: references/quick-reference.md
Includes:
- Command summary (decompile, recompile, align, sign, install)
- Smali quick reference
- Key file paths
- Common patterns cheat sheet.
- Redroid documentation: https://github.com/remote-android/redroid-doc
- Redroid Docker Hub: https://hub.docker.com/r/redroid/redroid
- Waydroid website: https://waydro.id
- Waydroid documentation: https://docs.waydro.id
- Waydroid GitHub: https://github.com/waydroid/waydroid
- casualsnek/waydroid_script: https://github.com/casualsnek/waydroid_script