- 数か月ぶりに Android アプリ開発を再開するため、軽い気持ちで Android Studio を最新版(2.3 → 3.1)にしたら、移行時のエラー解決にえらい手間取ったのでメモ。
build.gradle の dependencies
の compile
が廃止
Android Studio 2.x までは依存モジュールを compile
を使って羅列していたのが、 Android Studio 3.x では非推奨(廃止予定)になり、代わりに implementation
または api
のどちらか を使用する事になった。
// Android Studio 2.x での記述方法
dependencies {
compile '他のライブラリなど'
debugCompile '他のライブラリなど'
}
// Android Studio 3.x では以下のように書き換え
// ほとんどの場合は "compile" を "implementation" に変えるだけ
dependencies {
implementation '他のライブラリなど'
debugImplementation '他のライブラリなど'
}
implementation
と api
の違いについては、詳しくは以下のサイトで。ざっくり言うと api
は今までの compile
と同挙動。implementation
は compile
に比べてビルドの高速化が期待できる らしい。大抵のケースでは implementation
で問題ないし、そちらがオススメ、との事。
Flavor を使用する場合、Flavor Dimensions の指定が必須
productFlavors
を使用してビルド設定を切り替えているプロジェクトにて、以下のようなエラーが出るようになった。
All flavors must now belong to a named flavor dimension. Learn more at
https://d.android.com/r/tools/flavorDimensions-missing-error-message.html
全てのフレーバーは Flavor Dimensions に属さないといけない、と。
そもそも Flavor Dimensions て何?って状態だったので理解するのに時間がかかったが(詳しくは別記事)、Android Studio 3.x からは全てのフレーバーについて、必ず dimension
を指定しないといけなくなったらしい。
概念さえ理解してしまえば、テキトウな名前の dimension
を作って全フレーバーに明記するだけなので対応は簡単。
アプリとライブラリを同じ Build Variant で連動ビルドさせる方法の変更
Android Studio 2.x の頃は、アプリのプロジェクトにライブラリモジュールも連携させて、同じ Build Variant でビルドさせたい場合、
dependencies {
debugCompile project(path: ':mylib', configuration: 'debug')
releaseCompile project(path: ':mylib', configuration: 'release')
}
てな感じで結構面倒な記述をしないといけなかったのだけれど、Android Studio 3.x からは、以下だけで自動的に同じ Build Variant でビルドしてくれるようになった。
dependencies {
implementation project(':mylib')
}
この場合、アプリ側とライブラリ側で buildTypes
や productFlavors
の構成が全く同じなら問題ないのだけど、構成が違ってる場合はアプリ側の全ての Build Variant がライブラリ側の Build Variant と対応が取れるように指示しないといけなくなった。
詳しくは別記事 にまとめたけど、これはこれで地味に面倒。
2018.04 現在、NDK のビルドシステムに問題があり、ライブラリが依存関係に応じた適切な順序でビルドされない?
NDK を使用したアプリにて、C++のライブラリモジュールをアプリプロジェクトと連動でビルドさせようとしたところ、「リンク対象のライブラリのファイルが存在してない」 と怒られた。
調べてみたところ、本来ならばまず先にライブラリモジュールをビルドを済ませてからアプリモジュールのビルドに取りかかるはずが、依存関係無視でアプリモジュールから先にビルドしようとしてる模様。Android Studio 2.x ではこんな事はなかった。
ここで試しにライブラリモジュールだけ別途ビルドしてみたところ、まあ当然ビルドはできるようになったのだけど、それ以後も常にアプリの後にライブラリがビルドされるため、ライブラリ側の修正は必ず1手遅れて反映される事なり、使い物にならない。
で、Android Studio 3.x から何か仕様変更があったのかと調べてみても特に何も見つからず、公式サンプルでも同症状なのかなと Hello-libs サンプル を見直してみたところ、酷いやっつけ対応がされてた。
// Workaround library native code dependency issue in gradle 3.0.0
// refer to https://issuetracker.google.com/issues/69616088
// Note that the followings are only needed to generate lib package
// into $project/distribution directory, does NOT affect application module;
// Only enable these when want to build libs (together with note
// inside settings.gradle)
/*
tasks.whenTaskAdded { task ->
if (task.name == 'externalNativeBuildRelease') {
task.dependsOn ":gen-libs:externalNativeBuildRelease"
} else if (task.name == 'externalNativeBuildDebug') {
task.dependsOn ":gen-libs:externalNativeBuildDebug"
}
}
*/
要するに、gradle 3.x に問題があるので、ライブラリのビルドを試してみたい人はここをコメント解除すればとりあえずビルドはできるよ、てな感じ?。公式サンプルですらこんなだし、修正されるまではこれで対応するしかないのかね。
他にも StackOverflow で以下のような方法も見つけたけど、これだと毎回ライブラリ側のビルドがかかってしまうようで、上の方法に比べるとかなり遅い。
preBuild.dependsOn ":ライブラリ名:build"