Multidex

A compiled Android app doesn't ship as plain .class files — it's packaged into one or more DEX (Dalvik Executable) files. For a long time, a single DEX file could reference at most 65,536 methods, and once RecipeBox plus every library it depends on crossed that count, the build simply failed. Multidex is the fix: splitting the app's compiled code across more than one DEX file.

The 64K Method Limit

The limit comes from how the DEX format references methods internally — a method reference is a 16-bit index, so a single DEX file tops out at 65,536 method references, counting every method RecipeBox defines plus every method pulled in from Retrofit, Glide, Firebase, AndroidX, Room, and everything else on the dependency list from earlier lessons.

A classic mid-size app rarely writes 65K methods of its own code. It gets there by accumulating library dependencies — each one adds its own method count on top of RecipeBox's own classes, and large SDKs (analytics, ads, maps, Firebase) are common culprits.

The Build Error

When this limit is exceeded, the build fails with a message like this:

// Typical error when the method count is exceeded
com.android.tools.r8.internal.Exception:
Cannot fit requested classes in a single dex file
(# methods: 68420 > 65536)
Seeing this error is usually the first time a project actually needs multidex — it isn't something to configure preemptively for a small app.

Enabling Multidex (minSdkVersion Below 21)

On API levels before 21 (Android 5.0), the platform's own package installer only knew how to load a single classes.dex per app, so supporting multiple DEX files required extra plumbing at app startup, provided by the androidx.multidex library.

// app/build.gradle (Groovy DSL)
android {
    defaultConfig {
        minSdk 19
        multiDexEnabled true
    }
}

dependencies {
    implementation 'androidx.multidex:multidex:2.0.1'
}
// AndroidManifest.xml
<application
    android:name="androidx.multidex.MultiDexApplication"
    ... >
Explanation:
  • multiDexEnabled true tells D8/R8 to split the compiled code across several DEX files instead of failing.
  • Extending (or setting android:name to) MultiDexApplication installs the runtime support that loads the extra DEX files before any of RecipeBox's own classes are touched.

MultiDexApplication vs Manual MultiDex.install()

Setting android:name to MultiDexApplication only works if RecipeBox doesn't already have its own custom Application subclass. If it does — as most real apps do, for initializing Firebase or WorkManager at startup — the same behavior is added manually instead.

// RecipeBoxApp.java
public class RecipeBoxApp extends Application {

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}
Explanation: MultiDex.install() must run in attachBaseContext(), not onCreate() — the extra DEX files need to be loaded before any of the app's own classes (including things referenced from onCreate()) are resolved by the class loader.

Modern Projects: Mostly Automatic

Once minSdkVersion is 21 or higher, none of the manual setup above is needed at all. Android 5.0 introduced ART, which natively supports loading multiple DEX files, and the modern Android Gradle Plugin's D8 dexer automatically splits classes across DEX files whenever the method count requires it — no multiDexEnabled flag, no MultiDexApplication, no manual install call.

minSdkVersionMultidex supportWhat RecipeBox needs to do
< 21Not built into the OSSet multiDexEnabled true + use/extend MultiDexApplication
≥ 21Native (ART)Nothing — D8 splits DEX files automatically when needed
Most current Android projects set minSdkVersion comfortably above 21 already, which is why multidex configuration rarely shows up in modern tutorials — it's still worth understanding for older codebases and for the rare case of an extremely library-heavy app during multidex-related debugging.

Troubleshooting

Still hitting the method limit on minSdk 21+? → That's a different problem — DEX splitting handles the method count, but bloated dependencies still bloat the APK. See App Size Optimization.

App crashes with NoClassDefFoundError right after enabling multidex on an old minSdk? → Double-check attachBaseContext() calls MultiDex.install(this) before anything else runs.

Build is slow after enabling multidex? → Expected to some degree; splitting and merging DEX files adds work, which is one more reason modern minSdk levels avoid it entirely.

With DEX limits handled, the next lesson turns to App Bundle & Signing — packaging RecipeBox as an Android App Bundle and producing a properly signed release build for Google Play.