※ Built-in Shrinkerは、Android Gradle Plugin 3.3からR8に置き換わりました。
Androidには64k問題という開発者にとって非常につらい問題があります。
こやつはそれ自体よりも、multidex化によるビルド時間の増加によって引き起こされる開発イテレーションの低下のほうが問題になります。
proguardによる回避
proguardのshrink工程において、参照していないメソッドが削除され、これによって64k問題の回避が可能になります。
proguardの問題
proguardに難読化処理も含まれているため、debugビルドでかけるとデバッグ効率が悪くなります。
そのため、通常はreleaseビルドでない限りproguardをかけないのが一般的かと思います。
しかし、proguardをかけないということは前述のshrinkが行われないため、releaseビルドでは64kに達していないのにdebugビルドでは64kを超えてしまってい、やむなくmultidex化するということが起こります。
また、proguardはInstant Runに対応していないため、Instant Runを有効にしている場合も問題になります。
Built-in Shrinker
これらの問題を解決するためにgradle-plugin 2.0.0
で新たに、Built-in Shrinker
という仕組みが追加されました。
これは、難読化はせず、shrink処理のみを行うdebugビルドにおけるproguardの代替ツールです。
使い方はbuild.gradle
のdebug
のbuildType
に以下の設定をするだけです。
android {
…
buildTypes {
debug {
debuggable true
minifyEnabled true
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
minifyEnabled
をtrue
、useProguard
をfalse
にして、releaseビルド同様にproguardFiles
を設定します。
この設定により、debugビルドでもshrinkが有効になり、debugビルドだけ64kに達するということを回避できます。
体感のビルド時間は、「proguardなしよりも遅く、proguardより早い」程度になります。
なお、Built-in Shrinkerはmultidexをサポートしていないのでmultidexの設定は全て消す必要があります。
まあ状態としては排他になるはずなので、既存のmultidex設定を消す手間以外には問題にはなりません。
その他
警告あるぞエラーが出る
(gradle plugin 2.2.1で出なくなった?) 起きました
Error:Execution failed for task ':app:transformClassesWithNewClassShrinkerForDebug'.
> Warnings found during shrinking, please use -dontwarn or -ignorewarnings to suppress them.
ビルドすると、こんなエラーが出ることがあります。
以下の定義のファイルを用意して、
-ignorewarnings
proguardFiles
の定義に追加すればOKです。
android {
…
debug {
debuggable true
minifyEnabled true
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro', 'shrinker-rules.pro' // ← 追加
}
}
Analyze APK
Android Studio 2.2から、Analyze APKという機能が追加されました。
これを使うすることで既存のAPKの解析が行えるのですが、その中にはdexファイル内のメソッド数をカウントしてくれる機能があります。
こちらは
Build - Analyze APK
から利用できるので、こちらも活用してみてください。
KeepSafe/dexcount-gradle-pluginというプラグインを利用していましたが、メソッド数を知るためにわざわざプラグインを入れなくてもよくなったは良いですね。
dexguard
dexguard 7.2.07
時点では、どうやらdexguardプラグインはminifyEnabled
のみで有効化し、useProguard
の値を見てくれないみたいで、shrinkerを有効にする方法がわかりませんでした。
そもそもメソッド数を増やさないためには
Jake神の教えに従おう
Exploring Java's Hidden Costs
Android Studioで、デフォルトで無効になっているLintがあるので有効にしてこ?などの話があります。