Exploration of Android App Bundle Dynamic Loading with the Qigsaw Framework
Qigsaw, iQIYI’s open‑source framework released in 2019, enables low‑risk dynamic loading of Android App Bundle split APKs across all components and processes, offering Play‑Core‑compatible APIs, single‑hook stability, resource merging, and Tinker‑based hot updates, thereby simplifying plugin integration and reducing app size.
At the GMTC Global Front‑End Technology Conference, iQIYI senior engineer Chen Jiawei presented "Exploration of an Android App Bundle Dynamic Loading Solution" and announced the open‑source release of Qigsaw.
Qigsaw was first deployed in iQIYI’s app in January 2019. It provides a simple integration path for dynamic plugins, and after six months of production use the crash rate caused by Qigsaw accounted for less than 0.1% of total crashes. The framework was officially open‑sourced on June 26, 2019.
Core advantages of Qigsaw
Leverages the Android App Bundle development kit for rapid development.
Implements all App Bundle features, offering a "Play Core Library"‑compatible public API that developers can use by reading official documentation.
Supports dynamic loading of plugins in any process, including all four Android components.
Seamlessly switches to an App Bundle solution for overseas releases.
Uses a single hook with minimal private API access to ensure framework stability.
Google has been evolving strategies to reduce APK size. The timeline includes:
1. Multiple APK
Multiple APK allows developers to upload different APKs for different device configurations (CPU ABI, screen density, etc.). The Gradle configuration looks like:
android {
...
splits {
// Configures multiple APKs based on screen density.
density {
// Exclude densities that should not generate separate APKs
exclude "ldpi", "xxhdpi", "xxxhdpi"
}
// Configures multiple APKs based on ABI.
abi {
// ABIs to generate APKs for
include "x86", "x86_64"
// Do not generate a universal APK that contains all ABIs
universalApk false
}
}
}While Multiple APK reduces download size, it can lead to hundreds of APK variants, hurting iteration efficiency.
2. Android App Bundle
The App Bundle (.aab) contains all compiled code and resources. Google Play dynamically generates and signs a set of split APKs for each device at download time. Developers can also add dynamic‑feature modules that are installed on demand via the Play Core Library, offering capabilities similar to domestic plugin frameworks but with stronger integration.
3. Split APKs
Introduced in Android 5.0, Split APKs break a monolithic APK into multiple pieces (e.g., per‑ABI, per‑density). Installation can be performed via:
adb install-multiple [base-apk, split1-apk]
Using PackageInstaller at runtime.
When a third‑party app uses PackageInstaller , the system shows an installer UI for user confirmation. After installation the app process is killed and restarted so the new splits become active.
Play Core Library workflow (Qigsaw integration)
The iQIYI app requests a game APK through the Play Core Library.
Google Play fetches the game’s metadata, downloads the APK, and installs it.
All status updates (download progress, install result, etc.) are returned to the iQIYI app.
After installation the game APK can be used immediately (SplitCompat mode for Android < 7.0).
Qigsaw Architecture
Qigsaw builds on the Android App Bundle to package dynamic features, dramatically reducing development and maintenance cost. Its focus is on the installation and loading of split APKs.
Code loading : Qigsaw uses a single ClassLoader for both the base APK and split APKs. In DexPathList an Element and a NativeLibraryElement are created for each split.
Resource loading : The App Bundle assigns a unique resource ID to each asset. Base APK resources use Package ID 0x7F ; split resources receive decreasing IDs, avoiding conflicts. Qigsaw provides a loadResources method (injected by bytecode manipulation) to merge split resources at runtime.
Component loading : During manifest merging, split APK component declarations are merged into the base manifest. Consequently, Qigsaw does not support adding new components after the base APK is built, which aligns with current Android App Bundle behavior.
Multi‑process support : When a split is installed in the main process but an activity runs in a different process (e.g., :game ), a ClassNotFoundException can occur. Qigsaw solves this by either loading all installed splits at Application#attachBaseContext or hooking PathClassLoader to load missing components on demand.
public static class SessionParams implements Parcelable {
...
/** {@hide} */
@SystemApi
public void setDontKillApp(boolean dontKillApp) {
if (dontKillApp) {
installFlags |= PackageManager.INSTALL_DONT_KILL_APP;
} else {
installFlags &= ~PackageManager.INSTALL_DONT_KILL_APP;
}
}
...
}Qigsaw also integrates with Tinker for hot‑updating split APKs. During packaging, a JSON file (e.g., 1.0.0_ddddf54.json ) is generated in the base APK’s assets directory, describing each split’s name, URL, size, version, MD5, target processes, and SDK constraints. Updating this JSON via a Tinker patch enables split hot‑updates without a full app release.
{
"qigsawId": "1.0.0_ddddf54",
"appVersionName": "1.0.0",
"splits": [
{
"splitName": "java",
"url": "assets://java.zip",
"builtIn": true,
"size": 13915,
"version": "1.1@1",
"md5": "9ea0f98381dea0d16a313ea9c09cc4aa",
"workProcesses": [":qigsaw", ""],
"minSdkVersion": 14,
"dexNumber": 4
}
...
]
}Qigsaw is now used across iQIYI’s five business lines for mini‑programs and games. The project is open‑source, and contributors are invited to join its development.
iQIYI Technical Product Team
The technical product team of iQIYI
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.