How Ctrip Scaled Android with Plugin Architecture and Dynamic Loading
This article explains how Ctrip’s Android app adopted a plugin‑based, dynamic‑loading framework to overcome method‑limit, improve build speed, enable hot‑deployment, and support modular A/B testing, detailing the underlying principles, compilation changes, runtime resource and class loading, and the trade‑offs involved.
Ctrip’s Android application has been using a plugin‑based and dynamic‑loading framework for six months, proving its stability in production. The article shares the motivations, principles, implementation details, benefits, costs, and future directions of this approach.
Demand Driven
In 2014, business expansion and the split of Ctrip’s wireless department led to multiple BU‑specific teams, increasing communication overhead and exposing the 65,535 method limit of Android. Splitting dex files intelligently became essential, and plugin‑based dynamic loading offered hot‑deployment capabilities.
Principle
Plugin architecture requires handling two key problems: compile‑time resource and code compilation, and runtime resource and code loading.
How Android Compiles
Key steps involve aapt, javac, proguard, and dex. The diagram below highlights the main stages.
Resource Compilation
The aapt tool processes resources. Important flags include -I for adding existing packages, -G for generating ProGuard keep rules, and -J for outputting R.java. By assigning unique PackageID bytes to each plugin’s resources, ID conflicts are avoided.
Code Compilation
Plugins must include the host’s base.jar in the classpath and respect the host’s ProGuard rules for public/protected APIs.
Implementation
Plugin Resource Compilation
Use -I to reference host APK resources.
Add a custom --apk-module flag to assign distinct PackageID values.
Introduce --public-R-path so the plugin’s R class contains a copy of host resource IDs, avoiding massive code changes.
Plugin Code Compilation
Include host base.jar in the classpath.
Apply the host’s ProGuard configuration when obfuscating plugin code.
Runtime Resource Loading
Resources are accessed via AssetManager and Resources obtained from Context. By overriding the abstract methods in ContextImpl and using the hidden addAssetPath method via reflection, the plugin’s resources can be loaded based on the PackageID encoded in the resource ID.
Instrumentation is used to replace the default Resources instance for each Activity, ensuring seamless resource access.
Runtime Class Loading
Android’s PathClassLoader maintains a pathList of dex files. By appending plugin dex paths—similar to Google’s MultiDex library—plugins’ classes become available at runtime.
Benefits and Costs
Benefits
High cohesion and low coupling across BUs, reducing communication overhead.
Eliminates the method‑limit issue by splitting into multiple plugins.
HotFix capability for rapid issue resolution.
Modular A/B testing without tangled conditional code.
Significant compile‑time reduction for individual BUs.
Smaller host APK, faster startup, and reduced ANR risk.
Clear app size control per plugin.
Costs
Resource aliasing issues on certain devices (e.g., Samsung S6).
Potential resource name collisions, mitigated by naming conventions.
Enum ID conflicts handled similarly.
Limited external access to plugin resources before app launch.
Future Optimization
Support native .so libraries in plugins.
Enable advanced dependencies such as AAR, Maven, and library projects.
Improve IDE integration for easier plugin APK generation.
Open Source
The full implementation is available on GitHub at DynamicAPK . The Ctrip Mobile R&D team will continue to share practical experiences.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
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.
