KonifarPod

gradleでビルド時にjava.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536

   

Pocket

build.gradleを書いてsyncも成功して、いよいよビルド実行だという時にこんなエラーが出ました。

 

Error:Execution failed for task ':app:dexProductionDebug'.
> com.android.ide.common.internal.LoggedErrorException: Failed to run command:
 /Users/konifar/AndroidSDK/sdk/build-tools/19.1.0/dx --dex --force-jumbo --num-threads=4 --output /Users/konifar/Work/taptrip2-android/app/build/intermediates/dex/production/debug /Users/konifar/Work/taptrip2-android/app/build/intermediates/classes/production/debug
(略)
Error Code:
 2
 Output:
 UNEXPECTED TOP-LEVEL EXCEPTION:
 java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536
 at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:501)

 

java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536

これ何かと言うと、Androidではアプリのメソッド数が65536個を超えるとエラーになるようです。ライブラリも含めたコード全体でカウントされるらしいので、FacebookSDKとか色々使ってたら上限超えちゃってたみたいです。。。

詳しくはこちらで説明されています。⇒ DalvikバイトコードのMethod数65k制限について

 

で、どうすればいいか色々調べていたんですが、結局メソッドを減らすか、Proguardを使ってビルドするかしかないとのこと。。メソッド減らすのは辛いので、とりあえずデバッグでもproguardを使ってビルドするようにしました。手順は以下。

 

① app/build.gradle に記述を追加

runProguardオプションをtrueにして、proguardFilesを指定します。

android {
    buildTypes {
        debug {
            runProguard true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

 

② proguard-rules.pro を作成

proguardファイルはアプリによると思うので割愛しますが、例えばgsonを使う場合はこんな感じで書かないと動かなくなったりします。

-keepattributes Signature
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }

proguardは調べたり動かしたりしながらがんばって作っていくしかないんですかね。。。半日かけて色々調べながら作りました。

 

proguardを使ってビルドしたところ、どうやらメソッド数が65536以下になったようでちゃんとビルドできました。

試しにproguard-rules.proにほとんどのクラスの暗号化を無視する指定をしてみたところ、またエラー発生したので結構シビアなようです。

-keep public class * {
    public protected *;
}

 

これ他の大きいアプリとかはどうやってるのでしょうか?ライブラリとか使ったら結構すぐ上限行きそうな気がするんですが。。。proguard使う以外にベストプラクティスを知っている方がいたら教えてください。

 

Pocket

 - 未分類 ,