開発者コンソール

アプリ申請時のコンパイルエラーを回避する方法

アプリ申請時のコンパイルエラーを回避する方法

65,000個に近いメソッドを参照するアプリをAmazonアプリストアに申請すると、Dalvik Executable形式のバイトコードファイルにおける制限により、コンパイルエラーが発生します。

65,000個を超えるメソッドの参照に起因するエラーの発生

65,000個に近いメソッドを参照するアプリをAmazonアプリストアに申請すると、次のエラーメッセージがEメールで届くか、[App status] タブに表示されることがあります。

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

このエラーの原因は、Dalvikバイトコード(DEXファイル)で参照するメソッド数の上限が65,535になっていることにあります。詳細については、Androidドキュメントの64Kを超えるメソッドを使用するアプリ向けにMultidexを有効化するを参照してください。

Amazonのラッパーによるメソッドの追加

Amazonアプリストアではすべてのアプリをコードでラッピングして、各種レポート、分析、DRM、アプリのアップデートなどを開発者が実行できるようにしています。このラッパーにより、Amazonライブラリの参照先メソッドが1,627個追加され、アクティビティごとにメソッド数が9個ずつ増えます。このように参照先メソッドが追加されるため、アプリの参照先メソッドが65,000個近くに達した場合、メソッドの制限を超える可能性があります。

こうした制限は以前からありましたが、Android 5.0(Lollipop)のリリース以降、メソッド参照の上限を超えるケースが頻繁に発生するようになりました。Android 5.0に追加された機能により、アプリが参照するメソッドの数が増えやすくなっためです。 

この制限を回避するには、アプリでのメソッドの参照数を調べ、減らすことを検討してください。

メソッド参照数の取得

アプリが参照するメソッドの数、およびメソッドを参照するアプリの機能に関する情報を取得するには、GitHubにあるdex-method-countsツール(https://github.com/mihaip/dex-method-counts)を使用できます。

メソッド参照数の削減

メソッドの参照数を減らすには、余分なライブラリとメソッドをできるだけ削除します。または、ProGuardを-dontoptimize –dontobfuscateオプションを指定して使用すると、使用していないメソッドをビルド時にDEXファイルから削除できます。

上記の方法でもメソッド数を減らしきれない場合は、Multidexライブラリを使用してclasses.dexを複数のDEXファイルに分割します。

Multidexライブラリは、Android Gradleプラグインで使用できます。詳細については、64Kを超えるメソッドを使用するアプリ向けにMultidexを有効化するを参照してください。

multidex(複数のDEXファイルに分割する手法)アプローチでは、以下の点に注意してください。

  • 必ず、Android開発環境でGradleを使用してください。
  • Multidexを使っても十分な数のメソッドを削除できない場合は、いくつか追加で手順を実行する必要があります(次のセクションで概要を説明しています)。

上記で説明したdex-method-countsツールを使用すると、作成されるclasses.dexファイルのメソッド数を確認できます。

Multidexライブラリの使用

Android 5.0 Lollipopでは、サポートライブラリ(android-support-multidex.jar)が、Android SDKバージョン21.1.xおよびAndroid Support Library 21.0.3に導入されました。このサポートライブラリは、\android-sdk\extras\android\support\multidex\library\libsにあります。ライブラリには、MultiDexMultiDexApplicationの2つの新しいクラスが含まれており、Multidexの読み込みプロセスを簡略化できます。

Android 5.0はもともとセカンダリDEXファイルをサポートしているため、Android 5.0のみを対象とするアプリの場合、このライブラリは不要です。ただし、Android 5.0より前のバージョンでは、.dexファイルがAPKアーカイブからクラスローダーに追加されます。ライブラリを使用するとアーカイブがアプリのプライマリDEXファイルの一部になり、追加されたDEXファイルへのアクセスを管理できます。そのため、Android 5.0より前のリリースをターゲットにしたアプリでは、すべてこのライブラリを使用する必要があります。

このソリューションをAndroid 5.0よりも前のアプリに実装するには、次の操作を行います。

  1. Androidビルドツールを最新バージョンに更新していることを確認します。21.1.x以降のバージョンが必要です。
  2. プロジェクトにandroid-support-multidex.jarライブラリを追加します。このライブラリは、\android-sdk\extras\android\support\multidex\library\libsにあります。
  3. 以下の例に示すように、multiDexEnabled trueとMultidexの依存関係をbuild.gradleファイルのbuildConfigに追加します。

    android {
        compileSdkVersion 21
        buildToolsVersion "21.1.2"
    
        defaultConfig {
            ...
            minSdkVersion 14
            targetSdkVersion 21
            ...
            // Multidexサポートを有効にします。
            multiDexEnabled true
    }
     ...
    }
    dependencies {
        compile 'com.android.support:multidex:1.0.0'
    } 
    
  4. 以下のコードに示すように、android.app.Applicationクラスを上書きするか、MultiDexApplicationクラスをAndroidManifest.xmlファイルで宣言します。

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:name="android.support.multidex.MultiDexApplication">
        ...
    </application>
    
  5. プロジェクトに追加のライブラリがある場合は、必ずライブラリに対する事前のDEX化を無効にします。--multi-dexオプションは、事前にDEX化されたライブラリと互換性がありません。 

    以下のコードをapp/build.gradleファイルに追加すると、事前のDEX化を無効にできます。

    android {
    //  ...
        dexOptions {
            preDexLibraries = false
        }
    }
    
  6. multidex化アプリがAmazonアプリストアと申請プロセスに対して最適化されるようビルド手順を設定します。次の2つのオプションがあります。

    1. main-dex-listファイルを手動で作成します。app/build.gradleファイルで、以下を追加します。

      afterEvaluate {
          tasks.matching {
              it.name.startsWith('dex')
          }.each { dx ->
              if (dx.additionalParameters == null) {
                  dx.additionalParameters = []
              }
              dx.additionalParameters += '--multi-dex'
              dx.additionalParameters += "--main-dex-list=$projectDir/<filename>".toString()
          }
      }
      

      このコードでは、次の2つのパラメーターを使用します。

      • --multi-dex — ビルドプロセスでの分割メカニズムを有効にします。
      • --main-dex-list — メインのDEXファイルで添付する必要があるクラスのリストを含むファイルです。 

      multidex化アプリが申請を経て、適切にAmazonアプリストアで公開されるようにするには、--main-dex-listパラメーターを使用して、以下をメインの.dexファイルで指定する必要があります。

      • カスタムアプリ
      • アクティビティ
      • サービス
      • レシーバー
      • プロバイダー
      • インストルメンテーション
      • 注釈
    2. Studio 0.9.0とGradle 0.14.2を使用している場合は、multi-dexおよびmulti-dex-listパラメーターを無視し、ビルドツールで自動的にdx.additionalParametersパラメーターを60,000に制限します。この方法はほとんどのアプリで有効ですが、アプリで非常に多くのクラスを使用している場合は、Amazonアプリストアへの申請を通過するために、手動で最大数を60,000未満に設定しなければならない場合があります。

AndroidXライブラリの難読化の回避

AndroidXライブラリをmultidex化に使用している場合は、Proguardファイルに次の行を追加して、コードのAndroidXライブラリが難読化されないようにします。

-keep class androidx/multidex.** { *; }

関連リソース

main-dex-listの生成については、次の情報が役立ちます。


Last updated: 2023年10月2日