web-dev-qa-db-ja.com

Lollipopより古いAPIで64kの制限を超えましたが、新しいAPIではありません

だから、Android Lollipopよりも古いバージョンで、より新しいバージョンで正常に実行されているバージョンでアプリを実行しようとすると、64kのdexメソッドの制限が発生するのはなぜかと思います。

それは、古いバージョンで実行しているときにサポートライブラリが実際に参照されているためでしょうか?

これは私のグラドルです:

    apply plugin: 'com.Android.application'

    Android {
        compileSdkVersion 23
        buildToolsVersion '23.0.2'
    lintOptions {
        checkReleaseBuilds true
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }

    defaultConfig {
        applicationId "com.domain.myapp"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 27
        versionName "1.2"

        // Vector compat
        vectorDrawables.useSupportLibrary = true 
    }

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
}

dependencies {

    compile files('libs/commons-io-2.4.jar')
    compile files('libs/activation.jar')
    compile files('libs/additionnal.jar')
    compile files('libs/mail.jar')
    compile project(':libraries:preferencefragment')

    // Gmail API
    compile('com.google.api-client:google-api-client-Android:1.20.0') {
        exclude group: 'org.Apache.httpcomponents'
    }
    compile('com.google.apis:google-api-services-gmail:v1-rev29-1.20.0') {
        exclude group: 'org.Apache.httpcomponents'
    }

    // Play Services
    compile 'com.google.Android.gms:play-services-location:8.4.0'
    compile 'com.google.Android.gms:play-services-maps:8.4.0'
    compile 'com.google.Android.gms:play-services-ads:8.4.0'
    compile 'com.google.Android.gms:play-services-analytics:8.4.0'
    compile 'com.google.Android.gms:play-services-identity:8.4.0'

    // Support libraries
    compile 'com.Android.support:support-v4:23.3.0'
    compile 'com.Android.support:appcompat-v7:23.3.0'
    compile 'com.Android.support:cardview-v7:23.3.0'
    compile 'com.Android.support:design:23.3.0'

    compile 'com.github.bumptech.glide:glide:3.6.1'
    compile 'com.anjlab.Android.iab.v3:library:1.0.20'
    compile 'com.sothree.slidinguppanel:library:2.0.3'
    compile 'com.commit451:PhotoView:1.2.5'

    compile('com.github.afollestad.material-dialogs:core:0.8.5.7@aar') {
        transitive = true
    }
}

編集:

明確にするために:これは、たとえば、以下を実行しているエミュレーターでアプリを実行しようとすると発生します。 KitKat API 19

Gradleコンソールからのクラッシュログ:

...
:App:generateDebugInstantRunAppInfo
:App:transformClassesWithDexForDebug
AGPBI: {"kind":"error","text":"The number of method references in a .dex file cannot exceed 64K.\nLearn how to resolve this issue at https://developer.Android.com/tools/building/multidex.html","sources":[{}],"original":"UNEXPECTED TOP-LEVEL EXCEPTION:\ncom.Android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536\n\tat com.Android.dx.merge.DexMerger$6.updateIndex(DexMerger.Java:484)\n\tat com.Android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.Java:261)\n\tat com.Android.dx.merge.DexMerger.mergeMethodIds(DexMerger.Java:473)\n\tat com.Android.dx.merge.DexMerger.mergeDexes(DexMerger.Java:161)\n\tat com.Android.dx.merge.DexMerger.merge(DexMerger.Java:188)\n\tat com.Android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.Java:504)\n\tat com.Android.dx.command.dexer.Main.runMonoDex(Main.Java:334)\n\tat com.Android.dx.command.dexer.Main.run(Main.Java:277)\n\tat com.Android.dx.command.dexer.Main.main(Main.Java:245)\n\tat com.Android.dx.command.Main.main(Main.Java:106)\n","tool":"Dex"}

 FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':App:transformClassesWithDexForDebug'.
> com.Android.build.api.transform.TransformException: com.Android.ide.common.process.ProcessException: Java.util.concurrent.ExecutionException: com.Android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/Java'' finished with non-zero exit value 2

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

メッセージウィンドウからのクラッシュメッセージ:

:App:transformClassesWithDexForDebug
Error:The number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.Android.com/tools/building/multidex.html
Error:Execution failed for task ':App:transformClassesWithDexForDebug'.
> com.Android.build.api.transform.TransformException: com.Android.ide.common.process.ProcessException: Java.util.concurrent.ExecutionException: com.Android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/Java'' finished with non-zero exit value 2
19
Jakob

特定の質問に答えるには:

  • このメソッド数の制限は、DEX(Dalvik Executable)ファイルにあります。
  • この制限の一般的な回避策は、複数のDEXファイルを使用することです。
  • 古いバージョンのAndroidは複数のDEXファイルをネイティブにサポートしていません。
  • Lollipop以降、システムはネイティブにサポートしています。

そのため、古いデバイスでは失敗しますが、新しいデバイスでは機能します。サポートライブラリとは関係ありません。

私の答えにさらに有用なコンテンツを追加するには:

しかし、おそらく古いデバイスでそれを回避する方法が知りたいかもしれません。上記の箇条書きでWord nativelyを使用したことに注意してください。つまり、古いプラットフォームでサポートされるようにする回避策がありますが、アプリにそれらの回避策をコーディングする必要があります。

回避策(および問題自体も)は、このGoogleガイドで詳しく説明されています: http://developer.Android.com/tools/building/multidex.html

その基本は次のとおりです。

  • 依存関係にmultidexを追加compile 'com.Android.support:multidex:+'
  • android内のビルドスクリプトでmultiDexを有効にします-> default config multiDexEnabled true
  • マニフェストで、アプリケーションをMultidexApplicationAndroid:name="Android.support.multidex.MultiDexApplication"または、独自のアプリのApplicationをサブクラス化する必要がある場合、アプリケーションをそれから拡張します。
34
Budius

この問題は、インスタントランおよびLollipop以前のデバイスを使用しているときに発生します!

https://code.google.com/p/Android/issues/detail?id=208577https://code.google.com/p/Android/issues/detail? id = 196809

2
Boy

@Budiusに完全に同意します。マニフェストでアプリケーションクラスを指定する必要があります。そして、アプリケーションクラスにMultiDexApplicationを拡張させます。

もう1つ必要なことがあります。 MultiDexApplicationクラスでアタッチベースコンテキストを呼び出す

public class MyApplicationClass extends MultiDexApplication... {
....

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

これはLollipopの前後のデバイスでうまく機能しました。

2
drulabs

defaultConfig in gradleファイルにmultiDexEnabled = trueを追加する必要があります。