Mobile Development 8 min read

Dynamic Loading and Hotfix Implementation in Android Using DexClassLoader

This article explains the principles and practical steps for implementing dynamic class loading and hot‑fixes in Android by manipulating DexClassLoader, PathClassLoader, and bytecode, illustrated with the Qzone hot‑fix solution and open‑source Nuwa and HotFix projects.

Hujiang Technology
Hujiang Technology
Hujiang Technology
Dynamic Loading and Hotfix Implementation in Android Using DexClassLoader

A simple dynamic loading method is introduced, emphasizing its underlying ideas and principles.

Principle

ClassLoader

In Java, loading a class requires a ClassLoader . Android provides three class loaders: URLClassLoader (cannot load JARs on Dalvik), PathClassLoader (loads installed APKs from /data/dalvik-cache ), and DexClassLoader (the most suitable for plugin loading).

URLClassLoader can only load JAR files, which Dalvik cannot recognize directly, so it is unusable on Android.

PathClassLoader loads only already installed APKs by reading the ODEX files generated in /data/dalvik-cache . If the APK is not installed, a ClassNotFoundException is thrown.

DexClassLoader is ideal. Its constructor takes four parameters: dexPath (path to the target APK/JAR), dexOutputDir (directory for extracted dex files), libPath (C/C++ library path), and parent (the parent class loader, usually the current one).

Examining the Android framework source under dalvik.system shows that DexClassLoader inherits from BaseDexClassLoader , which contains a pathList field holding a list of dexElements . Each dexElement represents a single dex file.

Therefore, to achieve hot‑fix, we insert the plugin dex into the beginning of the dexElements array, so the class loader will prioritize the plugin classes and also provide a hot‑fix for the host APK.

ODEX Process

Android cannot load plain .class files; it uses dex files, which are heavily compressed versions of class files. During APK installation, Dalvik creates an optimized dex ( ODEX ) for better performance. The verification step may mark classes as CLASS_ISPREVERIFIED , preventing later replacement unless another dex is referenced.

Bytecode Manipulation

To avoid the pre‑verification flag, bytecode tools such as ASM are used:

ClassReader parses compiled class bytecode.

ClassWriter rebuilds or modifies class bytecode (e.g., changing names, attributes, methods).

ClassAdapter delegates method calls to another ClassVisitor .

Code Implementation

The open‑source project Nuwa demonstrates the approach. It uses reflection to obtain the host and patch PathList.dexElements arrays, concatenates them with the patch array first, and writes the merged array back to the class loader.

https://github.com/jasonross/NuwaGradle/blob/master/src/main/groovy/cn/jiajixin/nuwa/NuwaPlugin.groovy

Key points in the Nuwa script:

HotFixProcessors.processJar() scans all classes, computes hashes, and generates a patch JAR containing only modified classes.

HotFixProcessors.processClass() writes the modified bytecode to prevent the CLASS_ISPREVERIFIED flag.

Another similar open‑source implementation can be found at:

https://github.com/dodola/HotFix

Both solutions follow the same principle, so reviewing one is sufficient.

AndroidbytecodepluginClassLoaderhotfixDexClassLoader
Hujiang Technology
Written by

Hujiang Technology

We focus on the real-world challenges developers face, delivering authentic, practical content and a direct platform for technical networking among developers.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.