web-dev-qa-db-ja.com

dexを実行できません:[0、0xffff]にないメソッドID:65536

私は以前に様々なバージョンの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つだけです。デッキをするときにメモリ不足を防ぐためにこれを行う必要があるでしょう。

dexOptions {
        javaMaxHeapSize "4g"
}

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

dexOptions {
        jumboMode true
}

更新:あなたのアプリケーションが太っていて、メインアプリケーションの中にあまりにも多くのメソッドがある場合、あなたはあなたのアプリケーションを再編成する必要があるかもしれません。

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

336
Edison

更新3(11/3/2014)
グーグルはついに 公式説明 をリリースした。


更新2(10/31/2014)
Android用Gradleプラグインv0.14.0 multi-dex用のサポート が追加されました。有効にするには、build.gradleで宣言するだけです。

Android {
   defaultConfig {
      ...
      multiDexEnabled  true
   }
}

アプリケーションが5.0より前のAndroidをサポートしている場合(つまり、minSdkVersionが20以下の場合)、動的にアプリケーションのClassLoaderにもパッチを適用する必要があります。デックス。幸いなことに、これを行うための library があります。アプリの依存関係に追加します。

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

できるだけ早くClassLoaderパッチコードを呼び出す必要があります。 MultiDexApplicationクラスの documentation はそれをする3つの方法を提案します(それらのうちの1つを選ぶ、あなたにとって最も便利な方法)

1 - AndroidManifest.xmlMultiDexApplicationクラスをアプリケーションとして宣言します。

<?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 - Applicationクラスに MultiDexApplication classを拡張させます。

public class MyApplication extends MultiDexApplication { .. }

3 - MultiDex#installメソッドからApplication#attachBaseContextを呼び出します。

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

Update 1(2014/10/17):
予想通り、 multidex support はAndroid Support Libraryのリビジョン21で出荷されています。 Android-support-multidex.jarは/ sdk/extras/Android/support/multidex/library/libsフォルダーにあります。


マルチデックスサポートはこの問題を解決します。 dx 1.8ではすでにいくつかのdexファイルを生成することができます。
Android Lはマルチデックスをネイティブにサポートする予定です。次のバージョンのサポートライブラリでは、以前のリリースをカバーしてAPI 4に戻す予定です。

Anwar Ghuloumによる this Android Developers Backstageポッドキャストのエピソードで述べられています。私は 関連部分のトランスクリプト (そして一般的なマルチデックスの説明)を投稿しました。

371
Alex Lipov

すでに述べたように、あなたはあなたのプロジェクトとlibsにあまりにも多くのメソッド(65k以上)があります。

問題を回避する:Play Services 6.5以降およびsupport-v4 24.2以降でメソッド数を減らす

多くの場合、Google Playサービスは 20k +メソッド でメソッドを「無駄に」していることの主な疑いの1つです。 Google Playサービスのバージョン6.5以降では、多数の小規模なクライアントライブラリを使用して、アプリケーションに Google Playサービスを含めることができます 。 GCMとマップだけが必要な場合は、これらの依存関係のみを使用することを選択できます。

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

サブライブラリの完全な一覧とその責務は、公式のGoogleドキュメント にあります。

更新:Support Library v4 v24.2.0以降、以下のモジュールに分割されました。

support-compatsupport-core-utilssupport-core-uisupport-media-compatおよびsupport-fragment

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

ただし、support-fragmentを使用すると、他のすべてのモジュールに依存することになります(つまり、Android.support.v4.app.Fragmentを使用した場合には利点はありません)。

ここにsupport-v4 libの公式リリースノートがあります


多重定義を有効にする

Lollipop(別名ビルドツール21以降)以来、取り扱いは非常に簡単です。このアプローチでは、dexファイルの問題ごとに65kメソッドを回避して、アプリケーション用に複数のdexファイルを作成します。次のものをgradleビルドファイルに追加します( これは、65,000を超えるメソッドを使用するアプリケーションに関する公式のGoogleドキュメント から取得されます)。

Android {
    compileSdkVersion 21
    buildToolsVersion "21.1.0"

    defaultConfig {
        ...
        // Enabling multidex support.
        multiDexEnabled true
    }
    ...
}

dependencies {
  compile 'com.Android.support:multidex:1.0.1'
}

2番目のステップは、アプリケーションクラスを準備するか、またはアプリケーションを拡張しない場合は、AndroidマニフェストでMultiDexApplicationを使用することです。

これをApplication.Javaに追加してください。

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

または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>

MultiDexでOutOfMemoryを防ぐ

さらなるヒントとして、ビルド段階でOutOfMemory例外が発生した場合は、次のようにしてヒープを拡大できます。

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

これはヒープを4ギガバイトに設定します。

デックスヒープメモリの問題についての詳細は、この質問を参照してください。


問題の原因を分析する

メソッドのソースを分析するには、グラドルプラグイン https://github.com/KeepSafe/dexcount-gradle-plugin が依存関係との組み合わせで役立ちます。 gradleによって提供される木の例.

.\gradlew app:dependencies

Androidのメソッド数の詳細については、この回答と質問を参照してください。

77
patrickf

あなたのプロジェクトは大きすぎます。方法が多すぎます。アプリケーションごとに65536のメソッドしかありません。こちらを参照 https://code.google.com/p/Android/issues/detail?id=7147#c6

57
blobbie

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

同じ問題に直面し、依存関係セクションの私の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' 

私はcustom_rules.xmlビルドスクリプトと数行のコードを使用してこの問題を解決するサンプルプロジェクトを共有しました。

私は自分のプロジェクトでそれを使用しました、そしてそれは1M +デバイス(Android-8から最新のAndroid-19まで)で完璧に動作します。それが役に立てば幸い。

https://github.com/mmin18/Dex65536

6
mmin

Build.gradleに以下のコードを追加してみてください、それは私のために働いた -

compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
    multiDexEnabled true
}
5
Sunita

Android Studioを使用して問題(dexファイル参照)を分析できます。

ビルド - >分析APK ..

結果パネルで、classes.dexファイルをクリックしてください。

そして、あなたは見るでしょう:

enter image description here

2
alexshr

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

2
shimi_tap

Libsフォルダからjarファイルを削除して他のフォルダにコピーします。そして_Project Properties> Java Build Pathの選択、Librariesの選択、Add External Jarの選択、プロジェクトに削除されたjarの選択を選択Libsフォルダの代わりにライブラリ。今すぐあなたのプロジェクトをきれいにして実行します。 MultDexにAnyコードを追加する必要はありません。それは単に私のために働いた。

0
Lakshmanan

私は今日、同じ問題に直面していました。

Android STUDIOの場合...インスタントランを有効にする

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

それが役に立てば幸い

0
Abdul Waheed

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/**'
            }
        }
    }
  }
}
0
Oleg Khalidov