Create Account
Android Development • 9 min read • 132 views

How to Merge Split APKs (XAPK & APKM) into a Single Standalone APK: Complete Technical Guide

Learn how to deconstruct, merge, and rebuild Split APKs, XAPK, and APKM bundles into a single installable standalone APK. Master DEX consolidation, manifest patching, and signature generation.

APK
APK Tool Studio Team
Published on Oct 05, 2026 • https://apk.zoomnearby.com/

Since Google mandated the Android App Bundle (AAB) publishing standard on the Google Play Store, the traditional monolithic APK has largely been replaced by dynamic delivery systems. When users download an app today, Google Play serves a tailored combination of Split APKs—a minimal base binary coupled with specialized configuration splits for native CPU architecture (ABI), display density, and language localization.

While this architecture optimizes user download sizes, it introduces significant friction for Android developers, QA automation pipelines, penetration testers, and reverse engineers. Analyzing, modifying, or sideloading multi-part packages (such as .apks, .xapk, or .apkm files) across different devices or emulation environments requires consolidating these distributed fragments into a single, unified standalone APK.

In this comprehensive guide, we will break down the internal mechanics of Android Split APKs, examine why naive extraction fails, and walk through the complete technical process of merging DEX bytecode, resources, native libraries, and manifests into a production-ready standalone APK.

Understanding the Anatomy of Split APKs

To successfully merge an App Bundle delivery package, you must understand how Android categorizes its split components. When inspecting an extracted .xapk or .apks archive, you typically encounter the following structure:

  • Base APK (base.apk): Contains the primary AndroidManifest.xml, the core application entry points, core DEX bytecode, and fundamental assets common to all devices.
  • ABI Configuration Splits (split_config.arm64_v8a.apk, split_config.armeabi_v7a.apk): Contain native compiled shared objects (.so files) specific to device architectures located in the /lib/ directory.
  • Screen Density Splits (split_config.xxhdpi.apk, split_config.anydpi.apk): Contain pre-scaled bitmap drawables, vector drawables, and UI assets tailored to specific pixel densities.
  • Language/Locale Splits (split_config.en.apk, split_config.es.apk): House string tables (strings.xml) and localized value resources.
  • Dynamic Feature Modules: Optional on-demand feature modules containing isolated DEX bytecode, assets, and feature-specific manifests.

At runtime, the Android Package Manager uses the Context.createConfigurationContext() API to dynamically overlay these split resource tables onto the base context. Merging requires manually synthesizing these overlays into a single canonical resource table and bytecode index.

The Technical Challenges of APK Merging

A common mistake is attempting to extract the ZIP archives of all split APKs and simply repackaging their files into a single ZIP. This results in immediate installation or runtime crashes due to four fundamental conflicts:

  1. Manifest Split Enforcements: The base AndroidManifest.xml contains attributes such as android:isSplitRequired="true" and Google Play metadata tags that force the OS to reject monolithic execution.
  2. DEX Collision & Namespace Conflicts: Both the base APK and dynamic feature splits contain classes.dex files. Simply overwriting them destroys class definitions.
  3. Resource Table (ARSC) ID Mapping: Each split references resource identifiers allocated during bundle generation. Combining XML files without recompiling with aapt2 corrupts the string pool and style references.
  4. Signature Invalidation: Altering any file breaks APK Signature Schemes v1, v2, v3, and v4, requiring proper alignment and re-signing.

Step-by-Step: Merging Split APKs into a Standalone Binary

Step 1: Decompile the Base and Split Packages

First, disassemble the base APK and your target configuration splits using Apktool. For this example, we will merge the core base with the arm64-v8a native library split and the xxhdpi density split:

# Decompile base package
apktool d base.apk -o base_src -f

# Decompile ABI architecture split
apktool d split_config.arm64_v8a.apk -o split_abi_src -f

# Decompile density split
apktool d split_config.xxhdpi.apk -o split_density_src -f

# Decompile localized language split
apktool d split_config.en.apk -o split_lang_src -f

Step 2: Merge Native Shared Libraries (/lib)

Navigate to the decompiled ABI split directory and copy the architecture-specific native binaries into the base project's library tree:

# Create target architecture directory if missing
mkdir -p base_src/lib/arm64-v8a

# Copy all native shared objects
cp -r split_abi_src/lib/arm64-v8a/* base_src/lib/arm64-v8a/

Ensure that all required dependencies (e.g., libnative-lib.so, libc++_shared.so) are present. If you are supporting multiple architectures in your standalone build (e.g., universal APK), repeat this step for armeabi-v7a and x86_64.

Step 3: Consolidate Multi-DEX Smali Bytecode

If your split packages contain dynamic features or supplementary DEX files, their decompiled Smali code must be merged into numbered Smali directories in the base folder. In Apktool, primary classes reside in smali/, while secondary DEX files map to smali_classes2/, smali_classes3/, and so forth.

# Determine the highest existing smali folder in base_src
# If base_src has smali/ and smali_classes2/, place the split code into smali_classes3/
mkdir -p base_src/smali_classes3

# Copy Smali files from the split feature module
cp -r split_feature_src/smali/* base_src/smali_classes3/

Verify that there are no duplicate class definitions across directories to prevent DexIndexOverflowException or class verification errors during Dalvik/ART compilation.

Step 4: Merge Assets and Resources

Next, copy localized resources, drawables, and custom assets from the split directories into the base project:

# Merge density-specific drawables and mipmaps
cp -rn split_density_src/res/* base_src/res/

# Merge localized values (strings, arrays, plurals)
cp -rn split_lang_src/res/values* base_src/res/

# Merge custom asset files
cp -rn split_feature_src/assets/* base_src/assets/

Using the -n (no-clobber) flag prevents accidentally overwriting default fallback values in base_src/res/values/ with split-specific configs, ensuring a robust fallback mechanism.

Step 5: Patch AndroidManifest.xml

This is the most critical step. Open base_src/AndroidManifest.xml in an editor and perform the following cleanups:

  1. Remove the split attribute from the root <manifest> element if present.
  2. Locate the <application> tag and delete android:isSplitRequired="true".
  3. Remove all split metadata tags generated by Google Play delivery.

Here is an example of what to look for and remove:

<!-- REMOVE OR COMMENT OUT THE FOLLOWING ELEMENTS -->
<meta-data 
    android:name="com.android.vending.splits" 
    android:resource="@xml/splits0" />

<meta-data 
    android:name="com.android.vending.splits.required" 
    android:value="true" />

<meta-data 
    android:name="com.android.dynamic.apk.fused.modules" 
    android:value="base,feature_module" />

Also check apktool.yml in the base directory. If isFeature: true or split: true is present, set them to false or remove those keys so Apktool compiles a standard standalone APK package.

Streamlining the Process with APKTool Studio

Manually decompiling multiple split APKs, re-indexing multi-DEX directories, merging resource trees, and editing XML files can be time-consuming and error-prone. For a faster, zero-setup workflow, developers can leverage APKTool Studio—a modern, browser-based APK engineering suite.

With APKTool Studio, you can:

  • Decompile base APKs and inspect complex Smali code directly within a high-performance web IDE.
  • Batch-inspect and edit AndroidManifest.xml, resource values, and layout files with real-time syntax validation.
  • Rebuild, zipalign, and sign APK binaries instantly using custom or development keystores directly in the cloud without configuring local JDK, Android SDK, or build tools.

This makes testing modifications, verifying merged assets, and validating security patches frictionless across any operating system.

Rebuilding, Aligning, and Signing the Standalone APK

Once your file merges and manifest modifications are complete, compile the unified directory back into an installable APK binary.

1. Rebuild the APK

apktool b base_src -o merged_unsigned.apk --use-aapt2

Always pass the --use-aapt2 flag to ensure that resource references, complex vector assets, and attribute tables are compiled using Google's modern asset packaging tool.

2. Align Zip Archives (ZipAlign)

Android requires all uncompressed data (such as native .so files) to be aligned on 4-byte (or 16KB for Android 15+) page boundaries for efficient memory mapping via mmap():

zipalign -p -f -v 4 merged_unsigned.apk merged_aligned.apk

3. Sign with APK Signature Scheme v2/v3

Sign the aligned APK binary using apksigner to enable full compatibility with Android 7.0 through Android 15+:

apksigner sign --ks release.keystore \
  --ks-key-alias my-key-alias \
  --ks-pass pass:your_keystore_password \
  --key-pass pass:your_key_password \
  --out merged_release_signed.apk \
  merged_aligned.apk

To verify that all signature blocks are valid and ready for installation:

apksigner verify --verbose merged_release_signed.apk

Troubleshooting Common Merge Issues

1. ClassNotFoundException or NoClassDefFoundError

Cause: Smali classes from dynamic feature modules were copied into an invalid directory name or missed during multi-DEX allocation.
Fix: Verify that your Smali directories follow the strict naming convention: smali, smali_classes2, smali_classes3, etc., and confirm that classes referenced in AndroidManifest.xml exist in one of these directories.

2. Resources$NotFoundException

Cause: A resource ID defined in a layout or Java file exists in the code, but the corresponding XML/drawable from the configuration split was not merged into base_src/res/.
Fix: Re-examine your density and localized split packages to ensure all res/drawable-*, res/layout-*, and res/values-* folders were copied completely.

3. UnsatisfiedLinkError on Native Methods

Cause: The app attempted to invoke a JNI native method, but the .so file was either not copied to lib/<abi>/ or the ABI folder name does not match the device architecture.
Fix: Ensure all native libraries from split_config.<abi>.apk are located inside base_src/lib/<target_abi>/.

Conclusion & Best Practices

Merging Split APKs into a monolithic standalone package unlocks unrestricted testing, reverse engineering, and sideloading flexibility. By systematically consolidating DEX bytecode, merging native ABI libraries, synchronizing resource trees, and sanitizing the AndroidManifest.xml, you can recreate a fully functional standalone build from any App Bundle export.

For ongoing Android development, reverse engineering, and decompilation workflows, tools like APKTool Studio significantly accelerate your iteration cycle by providing intuitive, cloud-based disassembly, code modification, and automated APK signing in a single browser window.

Tags: #Split APK #XAPK #APK Merging #Smali #Android Development #APKTool Studio
Recommended

Related Tutorials & Guides

All Articles →