この記事はAndroid #2 Advent Calendar 2018 21日目の記事です。
はじめに
複数のproduct flavorを持つアプリ開発中、予想外の箇所でハマったので対応策を記載します。 想定読者は初級のAndroidアプリ開発者です。
なお、現時点で本事象の根本原因は分かっておらず、知見のある方がいらっしゃったらコメントくださると大変ありがたいです。
TL;DR
事象
特定Flavorの署名付きapkを作成するGradleタスクの実行に失敗する。 条件は以下。
- どのFlavorも、署名情報(storePassword等)は環境変数から取得
- build対象Flavorの署名情報の環境変数は設定済み
- build対象ではないFlavorの署名情報の環境変数は未設定
対策
build対象ではないFlavorのAPK署名用環境変数も正しく設定する。
詳細
ここからはサンプルコードを用いて説明します。サンプルコード: multi-flavor-app
アプリ構成
Flavorは2種類(darjeeling, assam)、各FlavorのsigningConfigs
は以下となっています。
署名に必要なstorePassword
, keyAlias
, keyPassword
を直接Gradleファイルに書くことは避けています。
AndroidStudioのGUIで指定する(Build -> Generate signed APK)以外の場合、buildを実行する環境に環境変数としてstorePassword等を設定しておく必要があります。
signingConfigs {
release {
storeFile file("./src/darjeeling_prd/keystore/darjeeling-prd.keystore")
storePassword System.getenv("darStorePass")
keyAlias System.getenv("darKeyAlias")
keyPassword System.getenv("darKeyPass")
}
}
signingConfigs {
release {
storeFile file("./src/assam_prd/keystore/assam-prd.keystore")
storePassword System.getenv("asmStorePass")
keyAlias System.getenv("asmKeyAlias")
keyPassword System.getenv("asmKeyPass")
}
}
アプリのbuild
フレーバー:darjeeling
のリリース用apkだけをbuildしたい場合、想定されるbuild手順は以下です。
-
- build環境に合わせて環境変数を設定
例)Mac OSで実行する場合
$ export darStorePass=XXXXXX $ export darKeyAlias=XXXXXX $ export darKeyPass=XXXXXX
- build環境に合わせて環境変数を設定
遭遇したエラー
で、想定ではここでdarjeeling
のリリースapkが作成されるはずだったのですが、実際には以下のようなエラーが出ました。
FAILURE: Build failed with an exception.
* What went wrong:
Some problems were found with the configuration of task ':app:packageDarjeeling_prdRelease'.
> No value has been specified for property 'signingConfig.keyAlias'.
> No value has been specified for property 'signingConfig.storePassword'.
名前的にdarjeeling
関連のタスクで何か起きている、かつ環境変数の読み込みに失敗していそうな気配が漂います。
そこで再度環境変数を設定しなおしてみたり、Dockeでのbuildに切り替えてみたりしてみたのですが、結果は同じでした。
またGradleファイルにログを仕込んで環境変数の値が正しく取得できていることも確認しました。
それでもやはり:app:packageDarjeeling_prdRelease'
で何か起きているようです。
解決策
darjeeling
のbuildに必要な設定に問題がないのであれば、疑うべきはassam
側の設定です。
いやーでもわざわざdarjeeling
のタスクを指定して実行しているし、別のFlavorの設定が影響することってある?エラーメッセージだってdarjeeling
関連のタスクに問題があるよと言っているし?と疑いつつ、assam
用の環境変数も設定して再度実行します。
すると結果はあっさりBUILD SUCCESSFUL。
つまりは、特定Flavorをbuildしたいときは、他Flavorのbuildも通る状態になっていることが必要ということでした。
雑感
普段はGUIから署名しているのですが、たまにコマンド叩いてみると意外な所で引っかかるんだなと勉強になりました。
あとGradleについて全然わかっていない。
以下は箇条書きで思ったことなど。
- Gradleのエラーハンドリングがよろしくなさそう
- タスク名に囚われるのはよくない
- もしかして署名情報を環境変数で保持する形式自体がイケてない…?(CI回すこと考えるとこうしておいたほうが管理しやすい気はする)