I have converted my application into MultiDex to bear with 64k dex limit. Now it looks like this:
public class App extends MultiDexApplication {
private App
The NoClassDefFound can happen with any arbitrary class that did not load up on a device with API earlier than Lollipop and with multidex enabled. If you set up ProGuard properly then you can easily get by without having the MultiDex overhead making your app slow to launch for your release builds, especially on old devices. However, you don't want ProGuard slowing you down while you develop your app in debug mode. If you try to launch your debug build with ProGuard disabled, you will start to get build errors like com.android.dex.DexIndexOverflowException: Cannot merge new index 72118 into a non-jumbo instruction!
So what you really want is ProGuard enabled and multidex disabled only on release builds, while debug builds should be the opposite with Proguard disabled and multidex enabled. You also have to be picky and use less dependencies, of course, because your release build will be subject to the 64K limit.
This requires setting up build.gradle to have buildTypes configs, and compiling the multidex support library dependency only for debug.
The Application subclass must also be set to derive from a different subclass depending on whether you're in multidex mode or not. This can be achieved using the gradle manifest merger principle, by defining an override manifest for your debug build, and then specifying your Application class differently.
Here's the relevant app module build.gradle:
android {
...
buildTypes {
debug {
minifyEnabled false //Disabled Proguard
multiDexEnabled true // Enabling multi-dex support.
}
release {
minifyEnabled true //Enabled Proguard
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
multiDexEnabled false // Disable multi-dex support.
}
}
dependencies {
debugCompile 'com.android.support:multidex:1.0.1' //debugCompile makes it included only for debug builds
...
}
}
If you don't use an Application subclass, then all you need to do is specify the name of the Application subclass android.support.multidex.MultiDexApplication as noted in https://developer.android.com/studio/build/multidex.html but you want to do this only for your debug build.
For this, you have to specify overriding files in the debug and release variant folder hierarchy, like so:
src
- main
- AndroidManifest.xml
- java/com/yourcompany/MyApplication.java (extends from BaseApplication)
- release
- java/com/yourcompany/BaseApplication.java (extends from Application)
- debug
- AndroidManifest.xml
- java/com/yourcompany/BaseApplication.java (extends from MultiDexApplication)
Yes, you create debug and release folders next to your main module's folder. Add the following files within:
This manifest will only be included in debug builds, and will be ignored for your release one.
public class BaseApplication extends Application {
}
public class BaseApplication extends MultiDexApplication {
}
public class MyApplication extends BaseApplication {
@Override
public void onCreate() {
super.onCreate();
//Init database, etc. etc.;
}
}
In this way, you can add your App's functionality into MyApplication.java while having differing base classes.