18
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Addressables × Play Asset Deliveryの調査メモ

Last updated at Posted at 2023-01-19

Play Asset Deliveryとは

参考: Google公式ドキュメント - Play Asset Delivery

旧来はGoogle Playにアップロードするapkには100MBという制限があって、収まりきらないリソースを別途アップロードする Opaque Binary Blob (OBB) という仕組みが存在した。
2021年8月からは Android App Bundle (ABB) という新しい仕組みが必須対応となり、この仕組みにおけるOBBに相当する機能が Play Asset Delivery。

Play Asset Deliveryではアセットパックという単位でリソースを扱う。アセットパックには以下の配信モードを紐付けることができる。

配信モード名 ダウンロードタイミング サイズ制限 ストアのアプリサイズ 削除可能性 注意事項
install-time アプリインストール時 1GB 含まれる AABの機能によって1つのapkとしてインストールされるので削除されない
fast-follow インストール直後 512MB 含まれる アプリの内部ストレージ領域に展開され、削除の可能性がある アプリ起動時にDLが完了していない可能性がある
on-demand リクエスト時 512MB 含まれない アプリの内部ストレージ領域に展開され、削除の可能性がある

Android App Bundle (AAB) とは

参考: Google公式ドキュメント - Android App Bundle

従来のapkは1つのファイルの中にx64やarm64といったCPUアーキテクチャ別のバイナリや、hdpiやxhdpiといった画面密度別のリソースなどが全て含まれていた。
これだと不要なデータまで含まれてしまって無駄なので、細かく分割して動的にapkを構成してインストールする仕組みが生み出された。その仕組みに対応したファイル形式がAndroid App Bundle。
イメージとしてはAndroid Developers Blogのgifが分かりやすい。

UnityにおけるAAB、Play Asset Delivery対応

参考: Unity公式ドキュメント - Play Asset Delivery

UnityでもAABおよびPlay Asset Deliveryを利用する仕組みは提供されている。Unity設定に示す項目を設定してビルドするだけでPlay Asset Delivery対応のAABが成果物として出力される。

Unityが内部でどのようなことをしているかはUnityの「Split Application Binary」を用いて、GooglePlay Storeで150MBより大きいアプリケーションを配信するという記事で詳しく調査されています。

仕様

  • 対象アセットのサイズが1GB未満の場合、全て1つのアセットパックにまとめて、install-time配信モードになる
    • この場合、追加実装は不要。ストリーミングアセットにアクセスする際のApplication.streamingAssetsPathで取得できるパスがアセットパックを考慮したものになっている
  • 対象アセットのサイズが1GB以上の場合、ストリーミングアセットで1つ、その他で1つのアセットパックにまとめて、大きい方がinstall-time、小さい方がfast-follow配信モードになる。
    • この場合、追加実装が必要fast-follow配信モードはインストール後にDLが開始するけれど、必要なタイミングまでにDLが完了しているとは限らないのでハンドリング処理が必要になる

カスタムアセットパックという仕組みを使うことで任意のアセット、任意の配信モードのアセットパックを作ることもできる。

Unity設定

① 出力をapkからaabにする

  1. File > Build Settings から Build Settingsウィンドウを開く
  2. PlatformのAndroid設定において、Build App Bundle (Google Play) を有効にする
    Export Project が有効の場合、Export for App Bundle という項目名に変化している

② ベースモジュールとアセットパックを分割する

  1. Edit > Project Settings から Project Settingsウィンドウを開き、Playerカテゴリを選択する
  2. Android タブを開き、Publishing Settings セクションを選択する
  3. Split Application Binary を有効にする

成果物(aab)に含まれるもの

  • ベースモジュール
    • プラグイン、スクリプト、アセット、ビルドインデックスが0のシーンの実行ファイル
  • アセットパック
    • 残りのシーン、リソース、ストリーミングアセットなど

実機上のパス

  • install-time
    • apk領域
    • jar:file:///data/app/[アプリのID]-[ハッシュ値]/split_[アセットパック名].apk!/assets/[アセットのパス]
  • fast-follow, on-demand
    • 内部ストレージ領域 (JavaのgetFilesDir()で取得できるパス)
    • /data/data/[アプリのID]/files/assetpacks/[アセットパック名]/[Bundle Version Code]/[Bundle Version Code]/assets/[アセットパス]

動作確認について

参考: Google公式ドキュメント - アセット配信をテストする

UnityエディタにAndroid実機を繋いでBuild And Runすれば動作確認ができる。
install-timeはアプリのインストールと一緒にインストールされる。
fast-followon-demandと同様の動作となる (明示的にリクエストしないとDLされない)。

注意事項は下記

  • Google Playからではなく外部ストレージからパックを取得するのでネットワークエラーのテストはできない
  • Wi-Fi接続を待つテストはできない
  • アセットパックのアップデートはサポートされない。事前にアンインストールしたりデータ消去する必要がある

多少手間はかかるけれど、Google Playの内部テストで動作確認するほうがトータルの手間は少ないかもしれない。

Addressable Asset Systemの場合

配置先がローカル (= ストリーミングアセット) になっているグループのAssetBundleが全てアセットパックに含まれる。
ファイルサイズが1GB未満でinstall-timeだけでいいなら特に追加実装は不要。
ファイルサイズが1GB以上になると前述のようにアセットパックが分割されて小さいほうがfast-follow配信モードになるので追加実装が必要。
※ 追加の実装 = fast-followon-demandのアセットパックの場合、必要時にDLされていなければDLする処理

追加実装はAddressables公式サンプルから必要なファイルを持ってきて、適宜改変するのが楽。

Warning
Addressables 1.21.1でGenerateLocationListsTask.csに入った変更によって、カタログに記載されるInternalIdのセパレータが/から\に変わったため、公式サンプルのコードのままでは正常に動作しない。
PlayAssetDeliveryAssetBundleProvider.csPlayAssetDeliveryInitialization.csのInternalIdに関する操作のところで、セパレータの置換をしてやれば動作するようになる。

作業手順

Unity設定も必要

  1. Addressables公式サンプルをクローンする
  2. Addressables-Sample/Advanced/Play Asset Delivery/Assets/PlayAssetDeliveryフォルダをAssets配下にコピーする
  3. Assets/AddressableAssetsData/AddressableAssetSettings.assetのインスペクタを開き、Build and Play Mode ScriptAssets/PlayAssetDelivery/Data/BuildScriptPlayAssetDelivery.assetを追加する
  4. 同インスペクタのInitialization ObjectsAssets/PlayAssetDelivery/Data/PlayAssetDeliveryInitializationSettings.assetを追加する
  5. Addressables Groupsウィンドウにて、Play Asset Deliveryに含めたいグループのインスペクタを開き、Add Schemaボタンを押下して、Play Asset Deliveryを選択して追加する。配信モードを選択できるので任意の設定を行う
  6. 同インスペクタのAsset Bundle Providerの項目をPlay Asset Delivery Providerに変更する
  7. Build & LoadPathsの項目をLocalに変更する
  8. アセットのビルドはDefault Build ScriptではなくPlay Asset Deliveryを用いる

実装調査

ビルドスクリプト

Play Asset Deliveryの実体はBuildScriptPlayAssetDelivery.csで、Default Build Scriptの実体であるBuildScriptPackedMode.csを継承している。内部の処理も継承元であるBuildScriptPackedModeのビルド処理を実行後にPlay Asset Delivery用の追加処理を実行しているだけなので、プラットフォーム問わず導入後はこちらに切り替えて構わない。

リソースプロバイダ

PlayAssetDeliveryProviderはアセットバンドル用のプロバイダであるAssetBundleProviderを継承している。
Android実機以外のプラットフォームでは親のAssetBundleProviderとして振る舞う。
Android実機ではアセットパックの状況を確認し、必要ならDLしてから親のAssetBundleProviderとして振る舞う。

グループスキーマ

CustomAssetPackSettings.assetのインスペクタでアセットパックの定義をする。
カスタムアセットパックを定義した場合、必要な[アセットパック名].androidpackフォルダやbuild.gradleを自動で生成する。
Play Asset Delivery用のグループスキーマを追加することで、グループごとにどのアセットパックに含めるか指定できる。

Unityの仕様変更

アセットパックの配置仕様がパッチバージョンで変わっているので注意が必要。
リリースノートでは UUM-15109 というIssueIDで表記されている。
2021では3.15から、2022では2.9から、2023では1.0から変更されている。

  • 変更前
    • [アセットパック名].androidpack/XXX.bundle
  • 変更後
    • [アセットパック名].androidpack/src/main/assets/XXX.bundle

AABを調べてみる

適当なサンプルプロジェクトをARMv7ARM64アーキテクチャ向けにビルドしたTest.aabを調べてみる。

 2023-01-19 17.17.27.png

aabを展開する

Google公式でbundletoolというツールが提供されている。これを使うことでAABファイルを展開できる。
Homebrewでもインストール可能 (Homebrew Formulae - bundletool) なのでMacOSやLinuxの場合はそちらを使うほうが楽かもしれない。

aabからapkセットを生成する

bundletoolのbuild-apksコマンドでaabからapkセットファイルを生成できる。
ビルドしたTest.aabからTest.apksを生成するコマンドは以下のようになる。

bundletool build-apks --bundle="./Test.aab" --output="./Test.apks" \
--ks="<keystoreFilePath>" \
--ks-pass="pass:<storePassword>" \
--ks-key-alias="<keyAlias>" \
--key-pass="pass:<keyPassword>"

 2023-01-19 15.38.45.png

apkセットを展開する

生成されたapkセット (.apks) ファイルはただのzipなので拡張子を変えれば展開できる。
splits配下に格納されているのがベースモジュール、asset-slices配下に格納されているのがアセットパック
ここから端末に合わせて動的に統合されたapkがインストールされる。

 2023-01-19 15.41.44.png

apkも展開してみる

apktoolを使うことでapkファイルの展開ができる。
Homebrewでもインストール可能 (Homebrew Formulae - apktool) なのでMacOSやLinuxの場合はそちらを使うほうが楽かもしれない。
apkを展開するコマンドは以下のようになる。

apktool d <apkFilePath>

base-master.apkの展開結果

  • Unityの基本的なアセットやglobal-metadata.dataがassets配下に格納されている
  • original配下にはapktoolによってデコードされる前の生のAndroidManifest.xmlが格納されている
  • res配下には画面密度別のアプリアイコンやstrings.xmlが格納されている
  • smali配下にはapktoolによってJava実行ファイルのclasses.dexをデコードしたsmaliファイルが格納されている

.smaliはAndroid Dalvik仮想マシンで使用されるアセンブリ言語であるSmaliで記述されたファイル

 2023-01-19 17.52.16.png

base-arm64_v8a.apkbase-armeabi_v7a.apkの展開結果

  • lib配下にはそれぞれarm64-v8a向けとarmeabi-v7a向けのネイティブバイナリが格納されている

 2023-01-19 17.49.59.png  2023-01-19 17.50.15.png

UnityDataAssetPack-master.apkの展開結果

  • assets配下にAddressablesにてローカル設定にしたアセットバンドルとカタログや設定ファイルが格納されている

 2023-01-19 17.57.38.png

aabをGoogle Play Consoleにアップロードしてみる

Google Play Consoleにaabをアップロードすると App Bundle エクスプローラでaabの詳細を確認することができる。

デバイス別のapkセットのDL

デバイス一覧からデバイスごとのapkセットをzip形式でDLすることができる。
試しに10.or E3BBTV TBBTV01のapkセットをDLしてみると、base.apkUnityDataAssetPack.apkは共通でCPUアーキテクチャ別のapkだけが異なるのが確認できた。

 2023-01-19 18.01.34.png

10.or Eのapkセット

 2023-01-19 16.16.35.png

3BBTV TBBTV01のapkセット

 2023-01-19 16.16.42.png

署名済みのユニバーサルAPKのDL

AABが登場する以前の1つのapkに全端末用のデータが入ったapkファイル形式でDLできる。
aabファイルをbundletoolとApktoolで展開した際に個々のapkに含まれていたファイルが全て1つのapkに格納されているのが確認できた。
Unityは1GB未満ならばinstall-timeになるのが仕様で、それもここで確認できた。

 2023-01-19 18.15.46.png

モジュールとアセットパックの確認

配信タブでは機能モジュールとアセットパックが確認できる。

機能モジュールにはbaseという名前のモジュールが1つあり、マスター1つとABI2種類の3つから構成されることが確認できた。
アセットパックにはUnityDataAssetPackという名前のアセットパックが1つあり、Unityの仕様通りにinstall-time配信モードであることが確認できた。

 2023-01-19 18.17.21.png

 2023-01-19 18.17.29.png
 2023-01-19 18.17.48.png

アセットパックを複数作った場合

Addressables公式サンプルのPlay Asset Deliveryのサンプルを利用してinstall-time, fast-follow, on-demandそれぞれのアセットパックを生成してみた。

aabを展開するとasset-slices配下に3つのアセットパックが格納されているのが確認できた。
またApp Bundle エクスプローラにてそれぞれのアセットパックに配信モードが適切に設定されているのが確認できた。

 2023-01-20 13.08.02.png

 2023-01-20 13.07.07.png

18
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?