2

I'm receiving this error in my android project:

Unable to execute dex: method ID not in [0, 0xffff]: 65536
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536

From all my research it's due to having too many methods in my android project - limit is 64k. However I have run scripts to count how many is currently in the project and it is coming up with 56k methods. Here is the script I am running.

The only addition to my project is that I have updated Parse from 1.4 to 1.7.

The project built and compiled after updating parse, but when I try to add any new code this error appears.

I was using Android Studio 0.8.9 when I first encountered this error. I have reverted back to Android Studio 0.8.6 and it is still occurring.

Opal
  • 81,889
  • 28
  • 189
  • 210
  • 6
    I think you are referencing some **external libaries**. The TOTAL method count exceeds 65K – Phantômaxx Oct 14 '14 at 09:37
  • 1
    To clarify @Funkystein 's comment, the total number of methods in your project **plus** the total number of methods in all libraries you are including. – Aleks G Oct 14 '14 at 11:27
  • You can check the method count of each dependency used in your project an android studio plugin, please check the answer http://stackoverflow.com/questions/30648172/gradle-library-duplicates-in-dependencies/36056607#36056607 – darwin Apr 08 '16 at 04:33

5 Answers5

5

I resolved this issue with this code, my problem is that google play services push my app over the limit. This removes the google play services that you app does not need. Put it at the bottom of your gradle build file

def toCamelCase(String string) {
String result = ""
string.findAll("[^\\W]+") { String word ->
    result += word.capitalize()
}
return result
}

afterEvaluate { project ->
    Configuration runtimeConfiguration = project.configurations.getByName('compile')
    ResolutionResult resolution = runtimeConfiguration.incoming.resolutionResult
    // Forces resolve of configuration
    ModuleVersionIdentifier module = resolution.getAllComponents().find { it.moduleVersion.name.equals("play-services") }.moduleVersion

String prepareTaskName = "prepare${toCamelCase("${module.group} ${module.name} ${module.version}")}Library"
File playServiceRootFolder = project.tasks.find { it.name.equals(prepareTaskName) }.explodedDir

Task stripPlayServices = project.tasks.create(name: 'stripPlayServices', group: "Strip") {
    inputs.files new File(playServiceRootFolder, "classes.jar")
    outputs.dir playServiceRootFolder
    description 'Strip useless packages from Google Play Services library to avoid reaching dex limit'

    doLast {
        copy {
            from(file(new File(playServiceRootFolder, "classes.jar")))
            into(file(playServiceRootFolder))
            rename { fileName ->
                fileName = "classes_orig.jar"
            }
        }
        tasks.create(name: "stripPlayServices" + module.version, type: Jar) {
            destinationDir = playServiceRootFolder
            archiveName = "classes.jar"
            from(zipTree(new File(playServiceRootFolder, "classes_orig.jar"))) {
                exclude "com/google/ads/**"
                exclude "com/google/android/gms/analytics/**"
                exclude "com/google/android/gms/games/**"
                exclude "com/google/android/gms/plus/**"
                exclude "com/google/android/gms/drive/**"
                exclude "com/google/android/gms/ads/**"
            }
        }.execute()
        delete file(new File(playServiceRootFolder, "classes_orig.jar"))
    }
}

project.tasks.findAll { it.name.startsWith('prepare') && it.name.endsWith('Dependencies') }.each { Task task ->
    task.dependsOn stripPlayServices
}
}
  • One of the BEST answers i saw! if i could UpVote it 100 times i would! Tx! – Shahar Jan 20 '15 at 08:43
  • Does this still work? Im getting a nullpointer when building, referring to the first line that includes ModuleVersionIdentifier (inside the .find{} call). – zoltish Jun 05 '15 at 13:00
3

You can now only import the pieces of Google Play Services that you use. This saves a lot of methods.

If you only use GCM, then you only need com.google.android.gms:play-services-gcm:7.5.0

Look here for the list: https://developers.google.com/android/guides/setup

Matt
  • 231
  • 1
  • 6
0

Are you using obfuscation? Proguard can remove non-used method, so you will fit in the limit. Also, you could split your project into modules. The 65k limit is per dex file, and module is separate dex file.

You could also configure Proguard to inline short methods- thay should remove a lot of short methods.

See http://fuzzproductions.com/news/the-mythical-android-method-limit-solved and How to solve the issue with Dalvik compiler limitation on 64K methods? for details.

Bartosz Bilicki
  • 12,599
  • 13
  • 71
  • 113
0

You might want to take a look at the new MultiDex support library.

http://blog.osom.info/2014/10/multi-dex-to-rescue-from-infamous-65536.html

Julian Suarez
  • 4,499
  • 4
  • 24
  • 40
0

The problem will rise when you update you google play services so instead of add the whole play service android studio provide a way to add particular api to the project Reference it will reduce your methods

Rakki s
  • 1,426
  • 1
  • 18
  • 42