Unable to execute dex: method ID not in [0, 0xffff]: 65536

前端 未结 12 2000
独厮守ぢ
独厮守ぢ 2020-11-21 18:48

I have seen various versions of the dex erros before, but this one is new. clean/restart etc won\'t help. Library projects seems intact and dependency seems to be linked cor

相关标签:
12条回答
  • 2020-11-21 18:58

    You can analyse problem (dex file references) using Android Studio:

    Build -> Analyse APK ..

    On the result panel click on classes.dex file

    And you'll see:

    0 讨论(0)
  • 2020-11-21 19:08

    Try adding below code in build.gradle, it worked for me -

    compileSdkVersion 23
    buildToolsVersion '23.0.1'
    defaultConfig {
        multiDexEnabled true
    }
    
    0 讨论(0)
  • 2020-11-21 19:09

    Faced the same problem and solved it by editing my build.gradle file on the dependencies section, removing:

    compile 'com.google.android.gms:play-services:7.8.0'
    

    And replacing it with:

    compile 'com.google.android.gms:play-services-location:7.8.0'
    compile 'com.google.android.gms:play-services-analytics:7.8.0' 
    
    0 讨论(0)
  • 2020-11-21 19:10

    As already stated, you have too many methods (more than 65k) in your project and libs.

    Prevent the Problem: Reduce the number of methods with Play Services 6.5+ and support-v4 24.2+

    Since often the Google Play services is one of the main suspects in "wasting" methods with its 20k+ methods. Google Play services version 6.5 or later, it is possible for you to include Google Play services in your application using a number of smaller client libraries. For example, if you only need GCM and maps you can choose to use these dependencies only:

    dependencies {
        compile 'com.google.android.gms:play-services-base:6.5.+'
        compile 'com.google.android.gms:play-services-maps:6.5.+'
    }
    

    The full list of sub libraries and it's responsibilities can be found in the official google doc.

    Update: Since Support Library v4 v24.2.0 it was split up into the following modules:

    support-compat, support-core-utils, support-core-ui, support-media-compat and support-fragment

    dependencies {
        compile 'com.android.support:support-fragment:24.2.+'
    }
    

    Do note however, if you use support-fragment, it will have dependencies to all the other modules (ie. if you use android.support.v4.app.Fragment there is no benefit)

    See here the official release notes for support-v4 lib


    Enable MultiDexing

    Since Lollipop (aka build tools 21+) it is very easy to handle. The approach is to work around the 65k methods per dex file problem to create multiple dex files for your app. Add the following to your gradle build file (this is taken from the official google doc on applications with more than 65k methods):

    android {
        compileSdkVersion 21
        buildToolsVersion "21.1.0"
    
        defaultConfig {
            ...
            // Enabling multidex support.
            multiDexEnabled true
        }
        ...
    }
    
    dependencies {
      compile 'com.android.support:multidex:1.0.1'
    }
    

    The second step is to either prepare your Application class or if you don't extend Application use the MultiDexApplication in your Android Manifest:

    Either add this to your Application.java

    @Override
      protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
      }
    

    or use the provided application from the mutlidex lib

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.android.myapplication">
        <application
            ...
            android:name="android.support.multidex.MultiDexApplication">
            ...
        </application>
    </manifest>
    

    Prevent OutOfMemory with MultiDex

    As further tip, if you run into OutOfMemory exceptions during the build phase you could enlarge the heap with

    android {
        ...
        dexOptions {
            javaMaxHeapSize "4g"
        }
    }
    

    which would set the heap to 4 gigabytes.

    See this question for more detail on the dex heap memory issue.


    Analyze the source of the Problem

    To analyze the source of the methods the gradle plugin https://github.com/KeepSafe/dexcount-gradle-plugin can help in combination with the dependency tree provided by gradle with e.g.

    .\gradlew app:dependencies
    

    See this answer and question for more information on method count in android

    0 讨论(0)
  • 2020-11-21 19:14

    The perfect solution for this would be to work with Proguard. as aleb mentioned in the comment. It will decrease the size of the dex file by half.

    0 讨论(0)
  • 2020-11-21 19:16

    The below code helps, if you use Gradle. Allows you to easily remove unneeded Google services (presuming you're using them) to get back below the 65k threshold. All credit to this post: https://gist.github.com/dmarcato/d7c91b94214acd936e42

    Edit 2014-10-22: There's been a lot of interesting discussion on the gist referenced above. TLDR? look at this one: https://gist.github.com/Takhion/10a37046b9e6d259bb31

    Paste this code at the bottom of your build.gradle file and adjust the list of google services you do not need:

    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
        }
    }
    
    0 讨论(0)
提交回复
热议问题