346

これまでさまざまなバージョンの dex erros を見てきましたが、これは新しいものです。クリーン/再起動などは役に立ちません。ライブラリ プロジェクトはそのままで、依存関係が正しくリンクされているようです。

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

また

Cannot merge new index 65950 into a non-jumbo instruction

また

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

tl;dr : Google の公式ソリューションがついに登場!

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

1 つだけ小さなヒントがあります。dex を実行するときにメモリ不足を防ぐために、これを実行する必要があります。

dexOptions {
        javaMaxHeapSize "4g"
}

信頼性の低い方法でこれを修正できるジャンボモードもあります。

dexOptions {
        jumboMode true
}

更新: アプリが太っていて、メイン アプリ内にメソッドが多すぎる場合は、次のようにアプリを再編成する必要がある場合があります。

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

4

12 に答える 12

57

プロジェクトが大きすぎます。メソッドが多すぎます。アプリケーションごとに 65536 メソッドしか存在できません。ここを参照してください https://code.google.com/p/android/issues/detail?id=7147#c6

于 2013-03-11T11:15:50.903 に答える
12

Gradle を使用している場合は、以下のコードが役立ちます。不要な Google サービスを簡単に削除して (それらを使用していると仮定して)、65k のしきい値を下回るように戻すことができます。この投稿へのすべてのクレジット: https://gist.github.com/dmarcato/d7c91b94214acd936e42

編集 2014-10-22 : 上記の要点について、多くの興味深い議論がありました。TLDR? これを見てください:https://gist.github.com/Takhion/10a37046b9e6d259bb31

このコードを 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
    }
}
于 2014-09-25T21:23:09.647 に答える
6

同じ問題に直面し、依存関係セクションの build.gradle ファイルを編集して以下を削除して解決しました。

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

そしてそれを次のように置き換えます:

compile 'com.google.android.gms:play-services-location:7.8.0'
compile 'com.google.android.gms:play-services-analytics:7.8.0' 
于 2015-08-19T23:31:12.183 に答える
2

これに対する完璧な解決策は、Proguard を使用することです。コメントでアレブが述べたように。dex ファイルのサイズが半分になります。

于 2014-07-31T11:01:33.030 に答える
0

gradle + proguard ソリューション:

afterEvaluate {
  tasks.each {
    if (it.name.startsWith('proguard')) {
        it.getInJarFilters().each { filter ->
            if (filter && filter['filter']) {
                filter['filter'] = filter['filter'] +
                        ',!.readme' +
                        ',!META-INF/LICENSE' +
                        ',!META-INF/LICENSE.txt' +
                        ',!META-INF/NOTICE' +
                        ',!META-INF/NOTICE.txt' +
                        ',!com/google/android/gms/ads/**' +
                        ',!com/google/android/gms/cast/**' +
                        ',!com/google/android/gms/games/**' +
                        ',!com/google/android/gms/drive/**' +
                        ',!com/google/android/gms/wallet/**' +
                        ',!com/google/android/gms/wearable/**' +
                        ',!com/google/android/gms/plus/**' +
                        ',!com/google/android/gms/topmanager/**'
            }
        }
    }
  }
}
于 2014-10-22T07:12:48.620 に答える
0

私は今日同じ問題に直面していましたが、うまくいったのは下にあります

ANDROID STUDIO の場合... Instant Run を有効にする

[ファイル] -> [設定] -> [ビルド、実行、デプロイ] -> [インスタント実行] -> [ホット スワップのインスタント実行を有効にする] をオンにします...

それが役に立てば幸い

于 2017-10-10T10:22:13.393 に答える
0

Libs フォルダーからいくつかの jar ファイルを削除し、他のフォルダーにコピーします。そして、_Project Properties に移動し、Java ビルド パスを選択し、ライブラリを選択し、Add External Jar を選択し、削除された jar をプロジェクトに選択し、保存をクリックします。これは、Referenced の下に追加されます。 Libs フォルダーの代わりにライブラリー。プロジェクトをクリーンアップして実行します。MultDex のコードを追加する必要はありません。それは単に私のために働いた。

于 2015-11-04T12:10:11.077 に答える