Mobile Development 14 min read

Overcoming Android’s 64K Method Limit with Multidex: Real‑World Strategies

This article examines the 64K method and linear memory constraints in large Android applications, compares the official multidex support library with custom dex‑splitting approaches used by WeChat, QQ, and Facebook, and proposes a testing‑based loading scheme that minimizes startup latency while keeping the primary dex lightweight.

WeChat Client Technology Team
WeChat Client Technology Team
WeChat Client Technology Team
Overcoming Android’s 64K Method Limit with Multidex: Real‑World Strategies

Android Official Solution

Android provides an official multidex support library . Enabling it is as simple as setting multiDexEnabled true in the defaultConfig block, which causes the build tools to split the application into multiple dex files named classesN.dex placed at the root of the APK.

defaultConfig {
    ...
    // Enabling multidex support.
    multiDexEnabled true
}

The split dex files are merged into a single OAT file during the ART compilation phase on Android 5.0+, reducing startup time. The main dex must contain classes referenced directly by the application entry points (e.g., Application, Activity, ContentProvider, Service), which is controlled by the mainDexClasses script available from SDK build tools version 21 onward.

mainDexClasses [--output <output file>] <application path>

The script analyzes compiled classes and generates a list of classes that must reside in the primary dex. It works in three steps: environment checks, ProGuard‑based shrinking using mainDexClasses.rules, and building the final list with MainDexListBuilder.

Example of direct and indirect reference classes:

public class MainActivity extends Activity {
    protected void onCreate(Bundle savedInstanceState) {
        DirectReferenceClass test = new DirectReferenceClass();
    }
}

public class DirectReferenceClass {
    public DirectReferenceClass() {
        InDirectReferenceClass test = new InDirectReferenceClass();
    }
}

public class InDirectReferenceClass {
    public InDirectReferenceClass() {
    }
}

For devices below Android 5.0, additional dex files must be loaded manually, typically in attachBaseContext:

public class HelloMultiDexApplication extends Application {
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}

If a class required at runtime is not in the primary dex, a NoClassDefFoundError can occur. The fix is to add the missing class to the --main-dex-list parameter:

afterEvaluate {
    tasks.matching { it.name.startsWith('dex') }.each { dx ->
        if (dx.additionalParameters == null) {
            dx.additionalParameters = []
        }
        dx.additionalParameters += '--multi-dex'
        dx.additionalParameters += "--main-dex-list=$projectDir/<filename>"
    }
}

This approach is simple and requires few dependencies, but large secondary dex files can cause noticeable black screens or ANR during the first load.

WeChat/QQ Loading Solution

WeChat (111,052 methods) and QQ split the app into one primary dex and two secondary dex files stored under assets/secondary-program-dex-jars/secondary-N.dex.jar. The secondary dexes are loaded in a background thread after verifying MD5 checksums to prevent tampering.

/**
 * Makes an array of dex/resource path elements, one per element of
 * the given array.
 */
private static Element[] makeDexElements(ArrayList<File> files, File optimizedDirectory,
                                         ArrayList<IOException> suppressedExceptions) {
    // implementation omitted
}

The packaging rule requires all Application, ContentProvider, and exported Activity / Service / Receiver classes and their indirect dependencies to reside in the primary dex, amounting to roughly 41,306 methods for WeChat.

public MainDexListBuilder(String rootJar, String pathString) throws IOException {
    path = new Path(pathString);
    ClassReferenceListBuilder mainListBuilder = new ClassReferenceListBuilder(path);
}

Loading logic checks whether the dex files have been optimized; if not, they are loaded in a separate thread. The approach yields good user experience but is complex and may eventually hit the method limit as the indirect dependency set grows.

Facebook Loading Solution

Facebook uses a lightweight nodex process to host secondary dex files. Only a minimal set of classes (the application and a dedicated NodexSplashActivity) are required in the primary dex.

<activity android:exported="false" android:process=":nodex"
    android:name="com.facebook.nodex.startup.splashscreen.NodexSplashActivity">

The nodex process is started first; if the dex is already initialized, it immediately launches the main UI. This reduces startup latency but adds ~100 ms overhead for the extra process.

Test Loading Solution

A proposed test‑based scheme keeps the primary dex minimal, similar to Facebook, while loading secondary dexes directly in the main process without spawning an extra process. The steps are:

Use the same asset‑based dex format as WeChat.

Ensure the primary dex contains only classes needed for dex loading.

During attachBaseContext, if dex is not initialized, pause the main process, start a helper process to load dex, then resume.

Process synchronization can be achieved via a temporary file that the loader creates and deletes; the main process polls the file every 100 ms. Tests show this does not trigger ANR because the main process is not in the foreground during the wait.

Summary

After exploring dex and ART details, the following actions are planned for WeChat:

Adopt the classesN.dex naming convention.

Validate the feasibility of the fourth loading scheme, handling cases where a Service launches the UI.

Continue testing and refining the approach.

The author welcomes feedback and discussion on the presented solutions.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Mobile DevelopmentperformanceAndroidMultidexDex Splitting
WeChat Client Technology Team
Written by

WeChat Client Technology Team

Official account of the WeChat mobile client development team, sharing development experience, cutting‑edge tech, and little‑known stories across Android, iOS, macOS, Windows Phone, and Windows.

0 followers
Reader feedback

How this landed with the community

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.