original post: https://matakucom.medium.com


せっかく Android Gradle Plugin 3.2 stable が出たので、Android Gradle Plugin 3.2.0-alpha18 で追加されていた android app bundle を使うにはどうすればよいか調べた。

App bundle とはユーザの端末ごとに適切なリソースを含んだ apk を提供できるフォーマットのことで、 play store へのアップロード時に apk でなく、aab ファイルと呼ばれる Android app bundle の形式のファイルをアップロードするようになる。

あとはユーザがアプリをダウンロードする際に、その端末に最適化された apk が play store 側で勝手にやってくれる最高の機能である。

Build an AAB

./gradlew bundle{buildVariant} で対応した build variant の app.aab が生成される。

Build APKs

試しにインストールしてみるには、端末のスペックに対応した apk を作る必要があるが、出力するには Google 製の bundletool を用いると便利。

apk を生成するには bundletool のbuild-apks を用いるとできる。以下は PC に接続しているデバイスに最適化されたものが生成される例だが、デバイス指定しないと、言語や解像度リソース全部入りの apk ができる。

# 接続されている端末に最適化されたもの 
# alias bundletool 'java -jar /path/to/bundletool.jar'
$ bundletool build-apks  \
               --bundle=/path/to/app.aab \
               --output=app.apks \        
               --ks=keystore.jks \        # keystore 指定
               --ks-pass=pass:password \  # pass: を付与する
               --ks-key-alias=alias \     # keystore の alias
               --key-pass=pass:password \ # pass: を付与する
               --connected-device

connected-device 指定でなく、端末のスペック (JSON) を指定することでも可能。bundletool の get-device-spec で adb に接続している端末の情報を JSON 形式で取得できる。

$ bundletool get-device-spec --output essential.json
$ cat essential.json
{
 “supportedAbis”: [“arm64-v8a”, “armeabi-v7a”, “armeabi”],
 “supportedLocales”: [“ja-JP”],
 “screenDensity”: 480,
 “sdkVersion”: 28
}
$ bundletool build-apks 
   --bundle=/path/to/app.aab \
   --output=app.apks \
   --device-spec essential.json

今回は Essential Phone で試したので、xxhdpi のものが含まれているようだ。あとは日本語ロケール設定なので日本語のリソースが含まれている。

$ unzip app.apks
Archive:  app.apks
 extracting: splits/base-ja.apk
 extracting: splits/base-xxhdpi.apk
 extracting: splits/base-master.apk

Install APKs

これらを adb install-multiple で指定すると良いのだろうか…と思っていたが、これも bundletool のコマンドで事足りるようだった。

$ bundletool install-apks --apks=app.apks

Release

Play console に aab ファイルをアップロードするだけで 、ユーザのインストール時に Google 側が最適化した apk 生成を勝手にやってくれるのでリリース時に大きな変更はなさそう。

Publisher API ももちろんあり、Fastlane も 2.96.0 で対応済み (gradle-play-publisher も 2.0.0 で対応予定らしい) 。

普段使っているので書くと Fastlane は以下のように apk 指定だったところを aab 指定にすると良い。

lane :deploy do    
  gradle(task: "bundleRelease")    
  supply(
    aab: /path/to/aab_file
    ... 
  )
end

今仕事で担当しているアプリで試してみたら 11% ほど容量が減っていた。

アプリの容量が大きいとアップデート時の通信量も大きくなると思うので、少ないに越したことはないし、必要な分だけ提供するのをシステム側が自動でやってくれるのはとてもありがたい。

これで Google のトラフィック量を少しでも抑えられる貢献ができるのかと思うと感慨深いものがある。

参考

About Android App Bundles -Android Developers
https://developer.android.com/guide/app-bundle/

Android App Bundle を使用してアプリのインストール サイズを小さくする -Play Console ヘルプ
https://support.google.com/googleplay/android-developer/answer/9006925