APK Analyzer and the Merged Android Manifest
APK Analyzer and the Merged Android Manifest
The APK Analyzer in Android Studio provides a way to inspect the contents of an APK, AAB, or ZIP file without reverse-engineering. While developers commonly use it to check file sizes and DEX method counts, one of its most useful capabilities is reconstructing binary XML resources, particularly the merged AndroidManifest.xml, into human-readable form. Understanding what happens during manifest merging, how the build tools encode the result, and how the APK Analyzer decodes it back is essential for debugging configuration conflicts, auditing library permissions, and verifying that build variants produce the intended final manifest. By the end of this lesson, you will be able to:
- Explain how the Android Gradle Plugin merges multiple manifest sources into a single final manifest.
- Describe how the merged manifest is encoded into binary XML inside the APK and how the APK Analyzer reconstructs it.
- Identify common manifest merging conflicts and how merge rules resolve them.
- Trace how library manifests contribute permissions, components, and metadata to the final application manifest.
- Apply the APK Analyzer to diagnose real-world issues with permissions, intent filters, and component registration.
Manifest Merging in the Android Build Pipeline
An Android application rarely has a single manifest file. The main src/main/AndroidManifest.xml declares the application's core components, but the build system must also incorporate manifests from several other sources: library (AAR) dependencies each carry their own AndroidManifest.xml, build type and product flavor source sets can overlay or override manifest entries, and navigation component libraries may contribute intent filters. The Android Gradle Plugin invokes the Manifest Merger tool to combine all of these into one canonical manifest that goes into the final APK.
The merger operates in a priority order. The highest priority manifest is the one from the application's build-type-specific source set, followed by the product-flavor-specific manifest, then the main source set manifest, and finally library manifests in dependency order. When two manifests declare the same element, the merger applies a set of default rules and explicit merge markers to decide the outcome:
// In build.gradle.kts, you can inspect the merge task
android {
buildTypes {
release {
// Manifest entries here override main and library manifests
manifestPlaceholders["appLabel"] = "MyApp"
}
}
}
The merger resolves each XML element according to a key attribute. For <activity>, <service>, <receiver>, and <provider>, the key is android:name. For <uses-permission>, the key is android:name as well. When the same keyed element appears in multiple sources, the higher-priority source wins for conflicting attributes. If there is a true conflict with no clear resolution, the build fails with a manifest merge error.
Merge Markers and Conflict Resolution
Developers can control the merging behavior by adding tools: attributes from the tools namespace. These markers instruct the merger how to handle specific elements or attributes:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- Remove a permission contributed by a library -->
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
tools:node="remove" />
<!-- Replace an activity declaration from a library -->
<activity
android:name="com.library.SomeActivity"
android:exported="false"
tools:node="replace" />
<!-- Override a specific attribute rather than the whole node -->
<application
android:allowBackup="false"
tools:replace="android:allowBackup" />
</manifest>
The available tools:node values are merge (the default), replace, remove, removeAll, and strict. When set to strict, the merger fails if there is any conflict rather than applying default resolution. This is useful for catching unexpected library contributions during CI builds.
This interview continues for subscribers
Subscribe to Dove Letter for full access to exclusive interviews about Android and Kotlin development.
Become a Sponsor