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


344

これまでに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


1
現在のデバイスでは使用できないAPIを使用していますか?
2013年

同じAPIバージョンをターゲットとする別のプロジェクトビルドが正常に機能するためです。
エジソン

では、利用できないAPIをある時点で使用しますか?if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)この関数が利用できない場合、この関数を呼び出さないような行で確認しますか?
2013年

ええ、そうです。プロジェクトは以前にうまく構築されました。また、行を逃した場合でも、実行時エラーになるはずです。
エジソン

おそらく、依存関係の1つがめちゃくちゃになっています。(現在、maven + project libのミックスを行っています)
Edison

回答:


379

アップデート3(2014年11月3日)
Googleがついに公式の説明をリリースしました。


アップデート2(
2014年10月31 日) Android向けGradleプラグインv0.14.0は、マルチdexのサポート追加します。有効にするには、それをbuild.gradleで宣言するだけです。

android {
   defaultConfig {
      ...
      multiDexEnabled  true
   }
}

アプリケーションが5.0より前のAndroidをサポートしている場合(つまり、minSdkVersion20以下の場合)、アプリケーションClassLoaderにも動的にパッチを適用する必要があります。これにより、セカンダリDexeからクラスをロードできるようになります。幸いなことに、それを行うライブラリがあります。それをアプリの依存関係に追加します。

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

できるだけ早くClassLoaderパッチコードを呼び出す必要があります。MultiDexApplicationクラスのドキュメントでは、これを行う3つの方法を提案しています(そのうちの1つを選択してください。最も便利な方法を1つ選択してください)。

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- ApplicationクラスでMultiDexApplicationクラスを拡張します。

public class MyApplication extends MultiDexApplication { .. }

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

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

アップデート1(2014年10月17日):
予想通り、Androidサポートライブラリのリビジョン21にmultidexサポートが含まれています。android-support-multidex.jarは/ sdk / extras / android / support / multidex / library / libsフォルダーにあります。


Multi-dexサポートはこの問題を解決します。dx 1.8では、すでにいくつかのdexファイルを生成できます。
Android Lはmulti-dexをネイティブでサポートします。サポートライブラリの次のリビジョンでは、API 4までの古いリリースをカバーする予定です。

これは、Anwar Ghuloumによるこの Android Developers Backstageポッドキャストエピソードで述べられました。私がしましたトランスクリプト掲示関連部分の(と一般的なマルチDEXの説明)。


2
ブログ投稿はセーバーです!:D
nadavfima 2014年

39
日食ユーザーのための何か?
ムハンマドババール

52
@MuhammadBabar Eclipseユーザー向けのAndroidスタジオがあります。
VipulKumar

2
@MohammedAliもちろん、可能であれば使用しないでください。あなたがいる場合しかし、あなたは何をすべき本当にあなたのアプリであまりにも多くのメソッドを持って、あなたはすでにあなたが言及したことのようなすべてのトリックを試してみましたか?ビルド時間について-これには、少なくとも開発ビルドには解決策があります-私の答えをここで参照してください:stackoverflow.com/a/30799491/1233652
Alex Lipov

2
Qt for Androidでは、multidexサポートを有効にした後でも、実行時にFacebook + TwitterのSDKを統合するときにアプリの問題が発生していました(特にこの1つのエラーにより、悪夢がありました:)java.lang.ClassNotFoundException: Didn't find class "org.qtproject.qt5.android.QtActivityDelegate" on path: DexPathList[[],nativeLibraryDirectories=[/vendor/lib, /system/lib]]。私の間違いは、5.0より前のAndroidサポートに追加の手順を適用していないことでした。とはいえ、オプション#3で解決し、ClassNotFoundException問題はなくなりました。ありがとう、@ Alex Lipov!
rob

78

すでに述べたように、プロジェクトとライブラリーに非常に多くのメソッド(65k以上)があります。

問題の回避:Play Services 6.5以降とsupport-v4 24以降でメソッドの数を減らします

多くの場合、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 docにあります。

更新: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ビルドファイルに追加します(これは、65kを超えるメソッドを持つアプリケーションの公式Googleドキュメントから取得されます)。

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.0"

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

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

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

これを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ギガバイトに設定されます。

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


問題の原因を分析する

メソッドのソースを分析するには、gradleプラグインhttps://github.com/KeepSafe/dexcount-gradle-pluginは、gradleが提供する依存関係ツリーと組み合わせて使用​​できます

.\gradlew app:dependencies

Androidでのメソッドカウントの詳細については、この回答と質問を参照してください


私はPlay Services 6.5以上のソリューションを使用しましたが、完全に機能しました。信じられないほど便利なヒント。本当にありがとう!
Hoang Nguyen Huu 2015

できればもっと賛成します。マルチデックスに頼る必要なく、この問題を修正せずに、使用していない他のすべてのPlay Servicesサービスを切り捨てます。ビルド時にパフォーマンスに悪影響を及ぼします。
Sean Barbeau 2015

1
私の目に涙を浮かべてあなたよりも あなたは私を救った
不眠症

私はGCMのクライアントライブラリを使用しました。これは、playサービスからgcmサービスのみを使用しているため、これで問題が解決しました。ありがとう!時間を節約します。
Ankit

57

プロジェクトが大きすぎます。メソッドが多すぎます。アプリケーションごとに存在できるメソッドは65536のみです。こちらをご覧くださいhttps://code.google.com/p/android/issues/detail?id=7147#c6


そうですか。このプロジェクトには多くの依存関係があります。Mavenを使用する前に問題なくビルドできましたが、Mavenが不要な依存関係を追加した可能性があります。再確認します。
エジソン

5
具体的には、Dalvik実行可能(dex)ファイルごとに65,536のメソッドしか存在できません。また、アプリケーション(APK)には、カスタムロードなどの複数のdexファイルを含めることができます。
Dennis Sheil、2013年

7
それは本当にアンドロイドの恥ずかしいバグです!とにかく、私の場合、ライブラリに含まれていて使用されていなかったJarを削除し、アプリをコンパイルしました
David

プロジェクトをクリーンアップする時間:/
Decoy

1
簡単な修正は、デバッグビルドでもProguardを使用することです
aleb

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

大好きです!Googleのような会社がパッケージを膨らませ続けるので、defが必要です。
エジソン

1
ニース-これは仕事のスポットでした。煩わしさや心配はありません!
スロット2014

注:これにより、Android StudioのAndroid SDKにあるGoogle Play Services jarが削除されました!元のjarファイルに戻すのは容易ではないため、悪い考えです。作成者は、スクリプトを変更して、ビルドディレクトリのjarを変更する必要があります。
2014年

@inder:その問題はありませんでした。しかし、私はcleanエクスクルードでサルをするたびに行う必要がありました(分析を使用しています)。
JohnnyLambada 2014年

これをリリースビルドから除外する方法
user1324936 14年

6

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

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

https://github.com/mmin18/Dex65536


1
スクリプトをありがとう。あなたはARTに気をつけるべきです。デバイスはデフォルトのdexのみを変換し、セカンダリdexは変換しない場合があります。Proguardソリューションをお勧めします。
エジソン

2
プロジェクトをEclipseにインポートして実行すると、エラーが発生します。「dexを実行できません:[0、0xffff]にないメソッドID:65536」。プロジェクトの使用法を説明できますか
カラカゴ2014

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' 

パーフェクト!私はGoogle Drive APIを使用するだけで動作します。
vedavis

5

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

compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
    multiDexEnabled true
}

2

これに最適なソリューションは、Proguardと連携することです。コメントで言及されたalebのように。dexファイルのサイズが半分になります。


1
特に、Google Playサービスjarのサイズがますます大きくなることに同意しました*(18kメソッド自体)
Edison 14

2

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

ビルド-> APKの分析..

結果パネルで、classes.dexファイルをクリックします。

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

ここに画像の説明を入力してください


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

0

Libsフォルダーからいくつかのjarファイルを削除し、他のいくつかのフォルダーにコピーし、_Projectプロパティ> Javaビルドパスの選択、ライブラリの選択、外部JARの追加の選択、プロジェクトへの削除されたjarの選択、保存をクリックします。これは[参照]の下に追加されますLibsフォルダーではなくライブラリ。プロジェクトをクリーンアップして実行します。MultDexのコードを追加する必要はありません。それは単に私のために働いた。


0

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

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

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

それが役に立てば幸い


1
これは私にとってうまくいきました-私は単にEnable Runを無効にし、Applyをクリックし、それを再度有効にし、それは再びうまくいきました。
MrBigglesworth
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.