If you have ever encountered an error Cannot fit requested classes in a single dex file when building an Android application, then you are already familiar with the problem that it solves MultiDexApplication. This is not just a technical term, but a key mechanism that allows you to bypass the platform's limitation on the number of methods in one Dalvik by the number of methods in one .dexfile. Without it, many modern applications simply could not work.

In this article we will look at what it is MultiDexApplicationwhy it appears in Android projects, how to integrate it correctly and what pitfalls may arise. You will learn when you really need to use multiple .dexfiles, and when the problem can be solved by optimizing the code. We will also look at alternative approaches that can save you from having to work with multidex at all.

The material will be useful both for novice developers who first saw an error about exceeding the limit of methods, and for experienced specialists who want to optimize the assembly of their application. We will not limit ourselves to theory - in the article you will find practical instructions, code examples and solutions to typical problems.

What is MultiDexApplication and why do you need it

MultiDexApplication is a class that is the successor of the standard android.app.Application, which allows an Android application to use multiple .dexfiles instead of one. But why is this necessary at all?

The point is the limitation of the virtual machine Dalvik (and partially ART), which historically supported no more than 65,536 methods in one .dexfile. This limitation is due to the file format .dexwhere methods are indexed by 16-bit values. When your application (along with all libraries) exceeds this limit, the build fails.

With the advent of Android 5.0 Lollipop (API 21) native support for multiple .dexfiles was introduced, but for older versions of Android additional configuration is required. Here MultiDexApplicationcomes to the rescue, which:

  • ๐Ÿ”น Loads additional .dexfiles when the application is launched
  • ๐Ÿ”น Ensures compatibility with devices on Android 4.4 (API 20) and below
  • ๐Ÿ”น Simplifies the build process for projects with a large number of dependencies

It is important to understand that MultiDexApplication is not a panacea, but rather a โ€œcrutchโ€ to bypass the limitation. It increases the cold start time of the application and can lead to performance problems, especially on older devices.

๐Ÿ“Š Have you encountered the method limit error in Android?
Yes, often
Yes, but rarely
No, but I have heard of her
No, Iโ€™m learning for the first time

How the limitation on 65,536 methods works

To understand why there is a need for MultiDexApplicationyou need to understand the nature of the limitation. Each .dexfile in Android contains:

  • ๐Ÿ“œ List of classes and their methods
  • ๐Ÿ”ข 16-bit indexes for links to methods
  • ๐Ÿ”— Link table between classes

A 16-bit index allows you to address a maximum of 65,536 unique methods (216 = 65,536). When your application, together with all libraries (Firebase, Retrofit, Room and others) exceeds this limit, the compiler cannot pack everything into one file and throws an error.

Interestingly, this number includes not only your methods, but also:

  • ๐Ÿงฉ Methods from all connected libraries (including transitive dependencies)
  • ๐Ÿ”„ Methods generated by the compiler (for example, for Kotlin or Data Binding)
  • ๐Ÿ“ฆ Methods from Android SDKif they are connected via compileOnly

Modern applications easily exceed this limit. For example, a project with Firebase, Dagger 2 i RxJava can contain 40-50 thousand methods only from libraries, not counting your own code.

๐Ÿ’ก

Use the tool ./gradlew :app:analyzeDependenciesto see the full list of dependencies and their size in methods.

When you really need it MultiDexApplication

Exceeding the limit of methods does not always mean that you need to immediately switch to multidex. Here are cases when MultiDexApplication is really necessary:

Scenario Is it necessary to use MultiDex Alternative solution
Application for Android 4.4 and below โœ… Yes Refuse support for older versions
Project with 70,000+ methods โœ… Yes Dependency optimization (see below)
Use Instant Run in Android Studio โœ… Yes Disable Instant Run or update Gradle Plugin
App only for Android 5.0+ with 66,000 methods โŒ No Include multiDexEnabled true without inheriting from MultiDexApplication

If your application is focused only on Android 5.0 (API 21) and above, you you can do without MultiDexApplicationby simply enabling support for multiple .dexfiles in build.gradle. However, for older versions of Android, you cannot do without inheriting from MultiDexApplication .

Also remember that using multidex:

  • ๐Ÿข Increases cold start time (sometimes by 500+ ms)
  • ๐Ÿ“ฆ Increases APK size (additional .dexfiles)
  • ๐Ÿ”„ May cause problems with Instant Run v Android Studio
๐Ÿ’ก

If your application only works on Android 5.0+, try first optimize dependencies before moving to multidex.

How to set up MultiDexApplication in a project

Integration MultiDexApplication consists of several steps. Here are step-by-step guide:

  1. Add a dependency to build.gradle (module level):

    implementation 'androidx.multidex:multidex:2.0.1'
  2. Enable multidex support in defaultConfig:

    android {
    

    defaultConfig {

    multiDexEnabled true

    }

    }

  3. Create a descendant class (or change an existing one Application):

    public class MyApplication extends MultiDexApplication {
    

    @Override

    public void onCreate() {

    super.onCreate();

    // Your initialization code

    }

    }

  4. Indicate your class in AndroidManifest.xml:

    <application
    

    android:name=".MyApplication"

    ...>

For projects on Kotlin the code will look like this:

class MyApp : MultiDexApplication() {

override fun onCreate() {

super.onCreate()

// Initialization

}

}

If you use ProGuard or R8, make sure that the obfuscation rules do not remove critical classes from additional .dexfiles. Add to proguard-rules.pro:

-keep class com.android.support.multidex.** { *; }

โ˜‘๏ธ Checking the MultiDexApplication setting

Done: 0 / 4

Project optimization: how to avoid MultiDexApplication

Before Instead of switching to multidex, try optimizing the project. Here are some effective ways to reduce the number of methods:

  • ๐Ÿงน Remove unnecessary dependencies. Use ./gradlew :app:dependenciesto find and remove unused libraries.
  • ๐Ÿ”„ Replace heavy libraries. For example, instead Guava use lighter alternatives.
  • ๐Ÿ“ฆ Use compileOnly for libraries needed only at the compilation stage.
  • ๐Ÿ› ๏ธ Include minifyEnabled and shrinkResources to remove unused code.

An example of dependency optimization in build.gradle:

dependencies {

// Instead of the full version of Firebase

implementation 'com.google.firebase:firebase-analytics-ktx'

// We use only the necessary modules

implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'

implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2'

// compileOnly for annotations

compileOnly 'org.jetbrains:annotations:24.0.1'

}

Another effective way is to use Dynamic Feature Moduleswhich allows you to separate parts of the application into separate .apkfiles that are loaded on demand. This not only reduces the size of the main .dexfile, but also optimizes the loading of the application.

Which libraries most often โ€œinflateโ€ the number of methods?

According to the analysis of popular projects, the most methods are added: Firebase (especially if you include all package), Play Services, Retrofit with many converters, RxJava/Coroutines with a full set of operators, as well as libraries for working with graphics (Glide, Picasso, Coil).

Typical problems with MultiDexApplication and their solutions

Even after correct configuration MultiDexApplication you may encounter problems. Here are the most common ones and ways to solve them:

โš ๏ธ Attention: If you use Instant Run v Android Studio, multidex may be unstable. It is recommended to either disable Instant Runor use Apply Changes instead Apply Code Changes.

1. Error "No implementation found for ... "

This error occurs when a class from the main .dexfile tries to access a class from an additional .dexfile that has not yet been loaded. Solution:

  • ๐Ÿ”ง Make sure that all critical classes (activities, services, providers) fall into the main .dexfile.
  • ๐Ÿ“ Create a file multidex-config.pro or multidex-config.txt in directory app/ and indicate in it the classes that should be in the main .dexfile.

2. Increasing startup time

Loading multiple .dexfiles increases the cold start time. To reduce this time:

  • โšก Use MultiDex.install(this) in attachBaseContext() instead of onCreate().
  • ๐Ÿ“‰ Optimize the main .dexfile, leaving only the most necessary classes in it.

Example of optimized code:

public class MyApp extends MultiDexApplication {

@Override

protected void attachBaseContext(Context base) {

super.attachBaseContext(base);

MultiDex.install(this);

}

}

3. Problems with ProGuard/R8

If after enabling obfuscation the application stops working, check:

  • ๐Ÿ” Rules proguard-rules.pro for conflicts with multidex.
  • ๐Ÿ“‹ Build logs for warnings about deleted classes.

Add to proguard-rules.pro:

-keep class com.android.support.multidex.** { *; }

-keep public class * extends android.support.multidex.MultiDexApplication

โš ๏ธ Attention: Work details ProGuard and R8 may change in new versions Android Gradle Plugin. Always check the latest settings in the official documentation.

Alternatives to MultiDexApplication

If you don't want to use MultiDexApplication, consider alternative approaches:

  • ๐Ÿ“ฆ Dynamic Feature Modules โ€”allow you to break the application into modules that are loaded on demand. Supported with Android 5.0 (API 21).
  • ๐Ÿ”„ App Bundles โ€”a new publication format that automatically optimizes code delivery to users.
  • ๐Ÿงฉ Micro-services โ€”moving some of the functionality into separate services or libraries.
  • ๐Ÿ—‘๏ธ Removing legacy code โ€”cleaning the project of unused classes and libraries.

Configuration example Dynamic Feature Module in build.gradle:

android {

dynamicFeatures = [':dynamic_feature']

}

dependencies {

implementation project(':dynamic_feature')

}

App Bundles is a modern approach that not only solves the problem with the limit of methods, but also optimizes the size of the APK downloaded by the user. Google Play automatically generates optimized APKs for different devices.

To switch to App Bundles, change in build.gradle:

android {

bundle {

language {

enableSplit = true

}

density {

enableSplit = true

}

abi {

enableSplit = true

}

}

}

FAQ: Frequently asked questions about MultiDexApplication

Is it possible to use MultiDexApplication in a library (AAR)?

No, MultiDexApplication intended only for the main APK application. If your library exceeds the limit of methods, you need to optimize its dependencies or split it into several modules. Libraries cannot contain multiple .dexfiles - this is only supported at the final APK level.

How can I learn how many methods are in my project?

You can use a plugin Android ClassCount or command:

./gradlew :app:analyzeDependencies

The command is also useful to count methods:

./gradlew :app:countDebugMethods

These tools will show the exact number of methods and help identify the most "heavy" dependencies.

Does MultiDexApplication affect performance?

Yes, using several .dexfiles increases the application's cold start time, especially on devices with Android 4.4 and below. On Android 5.0+ the impact is less noticeable due to native multidex support. To minimize impact:

  • Optimize the main .dexfile, leaving only critical classes in it.
  • Use MultiDex.install(this) in attachBaseContext().
  • Consider switching to App Bundles or Dynamic Features.
Is it possible to disable multidex for a debug build?

Yes, you can enable multidex only for a release build by adding to build.gradle:

android {

buildTypes {

debug {

multiDexEnabled false

}

release {

multiDexEnabled true

}

}

}

This will speed up building and running the application during development, but remember that a debug build may not work if the number of methods exceeds limit.

What to do if, after adding MultiDexApplication, the application crashes at startup?

The most common causes of crashes:

  1. Incorrect configuration AndroidManifest.xml (class not specified Application).
  2. Conflict with ProGuard/R8 (critical class removed).
  3. Problems with initializing libraries in additional .dexfiles.

Check the logs Logcat on subject ClassNotFoundException or NoClassDefFoundError. It often helps to explicitly indicate the classes that should be in the main .dexfile, via multidex-config.pro.