I think most android developer have been seen this error message before. This problem occurs when build android project to APK file.
What does it mean? Why it happens? and how can we fix it?
So when android application was compiled. The .java file will compiled to .class and compiled to .dex again. Then it will zip with resource file to .apk file.
So it's normally if your big project stuck in this problem. If your project isn't large too much. I think you should check your project by follow this article.
compile 'com.google.android.gms:play-services:8.4.0'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:cardview-v7:23.1.1'
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
compile 'com.android.support:gridlayout-v7:23.1.1'
compile 'com.android.support:mediarouter-v7:23.1.1'
compile 'com.android.support:palette-v7:23.1.1'
compile 'com.android.support:preference-v7:23.1.1'
compile 'com.android.support:support-v13:23.1.1'
compile 'com.android.support:preference-v14:23.1.1'
compile 'com.android.support:preference-leanback-v17:23.1.1'
compile 'com.android.support:leanback-v17:23.1.1'
compile 'com.android.support:support-annotations:23.1.1'
compile 'com.android.support:customtabs:23.1.1'
compile 'com.android.support:percent:23.1.1'
compile 'com.squareup:otto:1.3.8'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.okhttp3:okhttp:3.0.1'
Set minimum SDK version to 17 or higher and run it. You will see how this problem occurs.
1. Reduce dependencies in your project
Because of exceeding method count in your project. So you should fix the problem by reduce dependencies first.Check your project that contain with unused dependencies or not. If any dependencies can reduce or replace with another dependencies that compact than it, do it. For example, I found some projects are use Picasso and Glide together. Why don't you use one at all?
Most problems that I found from another developers is use Google Play Services in them project like this.
compile 'com.google.android.gms:play-services:8.4.0'
A pack of Google Play Services dependencies is very big, contain with 58,180 method!!
So the best way is choosing only some dependencies in Google Play Services that you really want to use it.
compile 'com.google.android.gms:play-services-location:8.4.0' compile 'com.google.android.gms:play-services-maps:8.4.0' compile 'com.google.android.gms:play-services-ads:8.4.0'
These dependencies are use only 27,766 methods. It look still too much method count for me but it is inevitable, because these dependencies are required some important dependencies such as Android Support v4, Base Google Play Services and Support Annotation.
Dependencies reducing by remove unnecessary dependencies is very important. You should do it first before use another way. Not only fix the exceed method count problem, but project building with gradle will be faster.
2. Set minimum SDK version to 21 or higher
This isn't great way, if your application need to support pre-lollipop version. But if based-on lollipop version (May required any feature in Android Lollipop)Why it worked when change minimum SDK to 21? That's because of Android 5.0 or higher are use ART (Android Runtime) that supported MultiDex instead of Dalvik. So ART can support more than 65,536 methods.
Inside the ART, when .class was compiled to .dex (Can be more than one). AOT (Ahead-of-Time) will compile .dex to .oat after that.
That why a project that required minimum SDK 21 will use ART and say goodbye to Over 65K Methods problem, yeah!
3. Use Proguard to reduce useless method
This solution is suits for Release build more than Debug build. Because it take a longer time and difficult to log analyze from LogCat.
Normally, Proguard will shrink and Obfuscate the code when you build a project, so unused method will be removed (But you can keep some method or class by config a proguard-rules.pro file) and also reduce total method count of your project.
4. OK! I give up and use MultiDex
MultiDex is the last way, if 3 ways that I mentioned aren't suitable for you. MultiDex allows you to build an APK with Dalvik by contain with multiple .dex with over 65,536 methods. Google has publish the MultiDex library to support with pre-Lollipop that use Dalvik to build project to .apk by required Android SDK Build Tools version 21.1 or higher.
android {
...
buildToolsVersion "21.1.0"
defaultConfig {
minSdkVersion 14
...
multiDexEnabled true
}
...
}
dependencies {
...
compile 'com.android.support:multidex:1.0.0'
}
In Android Manifest, <application> must use MultiDexApplication.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
...>
<application
...
android:name="android.support.multidex.MultiDexApplication">
...
</application>
</manifest>
But if you're using custom Application class. Just declare MultiDex method in to your class by follow this.
package com.akexorcist.multidextest;
import android.app.Application;
import android.content.Context;
import android.support.multidex.MultiDex;
public class MyApplication extends Application {
...
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
...
android {
...
productFlavors {
develop {
minSdkVersion 21
}
production {
minSdkVersion 14
multiDexEnabled true
}
}
...
}
dependencies {
...
compile 'com.android.support:multidex:1.0.0'
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.4.1'
}
}
apply plugin: 'com.getkeepsafe.dexcount'
This plugin will show the blue circle symbol in the front of each dependencies. And it will show method count information when the mouse pointer hover on it.
And recommend you to use 3rd party plugin to make the method count checking more convenient.