APK に含められるメソッドの総数は65535の上限があります。
何も対策を取らずに APK を作成するとインポートしたライブラリすべてのクラスが含まれてしまいます。開発したプロジェクトから使っていないクラスを含める必要はありません。
何も考えずにライブラリをどんどん追加していくとすぐにこの上限に達してしまいビルドできなくなってしまいます。
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536
trouble writing output: Too many field references: 131000; max is 65536. You may try using --multi-dex option.
今回はエラーが発生した時の対策方法を記述します。
以下の対策を取ることでこの問題が解決します。
対策方法は「4系」が含まれるか、含まれないかで対応が異なります。
Android 5 以上の場合の設定(minSdkVersion を 21 以上に設定している場合)
モジュール レベルの build.gradle の設定に「multiDexEnabled true」を追加します。
この設定を追加するだけでコンパイル時に自動で余計なメソッドを削除してくれます。
android { defaultConfig { minSdkVersion 21 targetSdkVersion 25 multiDexEnabled true } }
Android 5 以下が含まれる場合(minSdkVersion を 20 以下に設定している場合)
20 以下に設定している場合は、次のように Multidex サポート ライブラリを使用する必要があります。
サポートライブラリ等を利用して対策をしないと下記のようなエラーが発生してアプリが起動しません。
E/AndroidRuntime(10602): FATAL EXCEPTION: main
E/AndroidRuntime(10602): java.lang.NoClassDefFoundError
モジュール レベルの build.gradle の設定に「multiDexEnabled true」を追加します。
「dependencies」に「compile ‘com.android.support:multidex:1.0.1’」を追加します。バージョンは最新バージョンを調査して最新を指定しましょう。
android { defaultConfig { ... minSdkVersion 15 targetSdkVersion 25 multiDexEnabled true } ... } dependencies { compile 'com.android.support:multidex:1.0.1' }
次に、「AndroidManifest.xml」の「application」にて「android:name」を指定していない場合は、「android:name=”android.support.multidex.MultiDexApplication”」を指定します。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp"> <application android:name="android.support.multidex.MultiDexApplication" > ... </application> </manifest>
既に「Application」を継承して「AndroidManifest.xml」にて独自のクラスをしている場合は、「Application」を継承しているクラスを修正します。
「public class MyApplication extends Application」を
「public class MyApplication extends MultiDexApplication」へ変更します。
「Application」を「MultiDexApplication」へ変更できない、変更したくない場合は、
「attachBaseContext」をオーバーライドします。(外部ライブラリ等を利用していて、指定されたクラスの継承が必須等)
public class MyApplication extends OutApplication { @Override protected void attachBaseContext(Context context) { super.attachBaseContext(context); MultiDex.install(this); } }
これにて「Android 4」以下でも動作するようになります。
もちろん Gradle のコンパイルも問題なく完了します。