無法執行dex:方法ID不在[0,0xffff]中:65536

本文翻譯自:Unable to execute dex: method ID not in [0, 0xffff]: 65536

I have seen various versions of the dex erros before, but this one is new. 我以前見過各種版本的dex erros,但這是新的。 clean/restart etc won't help. 清理/重新啓動等無濟於事。 Library projects seems intact and dependency seems to be linked correctly. 圖書館項目似乎完好無缺,並且依存關係似乎已正確鏈接。

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

or 要麼

Cannot merge new index 65950 into a non-jumbo instruction

or 要麼

java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536

tl;dr : Official solution from Google is finally here! tl; dr :來自Google的官方解決方案終於來了!

http://developer.android.com/tools/building/multidex.html http://developer.android.com/tools/building/multidex.html

Only one small tip, you will likely need to do this to prevent out of memory when doing dex-ing. 只有一個小技巧,您可能需要執行此操作,以防止在進行排序時內存不足。

dexOptions {
        javaMaxHeapSize "4g"
}

There's also a jumbo mode that can fix this in a less reliable way: 還有一種巨型模式可以用不太可靠的方式解決此問題:

dexOptions {
        jumboMode true
}

Update: If your app is fat and you have too many methods inside your main app, you may need to re-org your app as per 更新:如果您的應用很胖,並且您的主應用中包含太多方法,則可能需要按照

http://blog.osom.info/2014/12/too-many-methods-in-main-dex.html http://blog.osom.info/2014/12/too-many-methods-in-main-dex.html


#1樓

參考:https://stackoom.com/question/11olr/無法執行dex-方法ID不在-xffff-中


#2樓

Your project is too large. 您的項目太大。 You have too many methods. 您有太多方法。 There can only be 65536 methods per application. 每個應用程序只能有65536個方法。 see here https://code.google.com/p/android/issues/detail?id=7147#c6 看到這裏https://code.google.com/p/android/issues/detail?id=7147#c6


#3樓

I've shared a sample project which solve this problem using custom_rules.xml build script and a few lines of code. 我共享了一個示例項目,該示例項目使用custom_rules.xml構建腳本和幾行代碼來解決此問題。

I used it on my own project and it is runs flawless on 1M+ devices (from android-8 to the latest android-19). 我在自己的項目中使用了它,並且它在1M +設備(從android-8到最新的android-19)上完美運行。 Hope it helps. 希望能幫助到你。

https://github.com/mmin18/Dex65536 https://github.com/mmin18/Dex65536


#4樓

The perfect solution for this would be to work with Proguard. 完美的解決方案是與Proguard合作。 as aleb mentioned in the comment. 正如評論中提到的aleb。 It will decrease the size of the dex file by half. 它將使dex文件的大小減少一半。


#5樓

The below code helps, if you use Gradle. 如果您使用Gradle,則以下代碼會有所幫助。 Allows you to easily remove unneeded Google services (presuming you're using them) to get back below the 65k threshold. 允許您輕鬆刪除不需要的Google服務(假設您正在使用它們),使其恢復到65k閾值以下。 All credit to this post: https://gist.github.com/dmarcato/d7c91b94214acd936e42 此帖子的全部功勞: https : //gist.github.com/dmarcato/d7c91b94214acd936e42

Edit 2014-10-22 : There's been a lot of interesting discussion on the gist referenced above. 編輯2014-10-22 :關於上面提到的要點,有很多有趣的討論。 TLDR? TLDR? look at this one: https://gist.github.com/Takhion/10a37046b9e6d259bb31 看看這個: 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: 將此代碼粘貼到build.gradle文件的底部,並調整不需要的Google服務列表:

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
    }
}

#6樓

Update 3 (11/3/2014) 更新3(11/3/2014)
Google finally released official description . 谷歌終於發佈了官方描述


Update 2 (10/31/2014) 更新2(10/31/2014)
Gradle plugin v0.14.0 for Android adds support for multi-dex. 適用於Android的Gradle插件v0.14.0 添加了對多dex的支持 To enable, you just have to declare it in build.gradle : 要啓用,只需在build.gradle中聲明它即可

android {
   defaultConfig {
      ...
      multiDexEnabled  true
   }
}

If your application supports Android prior to 5.0 (that is, if your minSdkVersion is 20 or below) you also have to dynamically patch the application ClassLoader , so it will be able to load classes from secondary dexes. 如果您的應用程序支持5.0之前的Android版本(也就是說,如果您的minSdkVersion爲20或更低),那麼您還必須動態修補應用程序ClassLoader ,以便能夠從二級dexes加載類。 Fortunately, there's a library that does that for you. 幸運的是,有一個可以爲您完成此任務。 Add it to your app's dependencies: 將其添加到應用程序的依賴項中:

dependencies {
  ...
  compile 'com.android.support:multidex:1.0.0'
} 

You need to call the ClassLoader patch code as soon as possible. 您需要儘快調用ClassLoader補丁代碼。 MultiDexApplication class's documentation suggests three ways to do that (pick one of them , one that's most convenient for you): MultiDexApplication類的文檔提出了三種實現方法(選擇其中一種 ,一種對您來說最方便):

1 - Declare MultiDexApplication class as the application in your AndroidManifest.xml : 1-在您的AndroidManifest.xml MultiDexApplication類聲明爲應用程序:

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

2 - Have your Application class extend MultiDexApplication class: 2-讓您的Application類擴展MultiDexApplication類:

public class MyApplication extends MultiDexApplication { .. }

3 - Call MultiDex#install from your Application#attachBaseContext method: 3-從您的Application#attachBaseContext方法調用MultiDex#install

public class MyApplication {
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
        ....
    }
    ....
}

Update 1 (10/17/2014): 更新1(10/17/2014):
As anticipated, multidex support is shipped in revision 21 of Android Support Library. 如預期的那樣 ,Android支持庫的修訂版21中提供了對multidex的支持 You can find the android-support-multidex.jar in /sdk/extras/android/support/multidex/library/libs folder. 您可以在/ sdk / extras / android / support / multidex / library / libs文件夾中找到android-support-multidex.jar。


Multi-dex support solves this problem. Multi-dex支持解決了這個問題。 dx 1.8 already allows generating several dex files. dx 1.8已經允許生成多個dex文件。
Android L will support multi-dex natively, and next revision of support library is going to cover older releases back to API 4. Android L將原生支持多dex,並且支持庫的下一個版本將涵蓋API 4之前的較早版本。

It was stated in this Android Developers Backstage podcast episode by Anwar Ghuloum. Anwar Ghuloum在 Android Developers Backstage播客集中對此進行了說明。 I've posted a transcript (and general multi-dex explanation) of the relevant part. 我已經發佈了相關部分的成績單 (和一般的多dex解釋)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章