ファイルサイズの大きなAndroidアプリを配信する技術 - エムスリーテックブログ

エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

ファイルサイズの大きなAndroidアプリを配信する技術

【マルチデバイスチーム ブログリレー3日目】

エンジニアリンググループ マルチデバイスチーム(iOS/Androidアプリの開発を担当)の渡辺です。

マルチデバイスチームで開発している「臨床ポケット」アプリは、医師が臨床現場で行う判断をエビデンスに基づいて支援するアプリです。 実際の医療現場ではスマホの通信状況が芳しくないことも多く、インターネットに接続できる前提だといざというときに利用ができない場合があります。 臨床ポケットではあらかじめ必要なデータをアプリにバンドルしておくことで、オフラインでの利用を可能にしました。

iOSアプリの開発時は何も問題なくアプリをリリースできましたが、AndroidアプリはGoogle Play ConsoleでApp Bundleのアップロード時にエラーが出ました。

この記事では、ファイルサイズの大きなAndroidアプリを配信するために実施した対応を紹介します。

臨床ポケットアプリについて

臨床ポケットアプリ Android版では、現在メインコンテンツとして表計算ツールを提供しています。 ツールはHTMLとJavaScriptで実装されており、WebViewで表示しています。 現時点では398個のツールが存在し、未圧縮状態で約844MB、リリースビルド生成時に圧縮され、aabファイルのサイズは約210MBになりました。

制限を10MB程度オーバーしているだけなので、プロジェクト構成を見直せば制限に収まるかもしれません。 しかし今後もツールを追加し続ける予定のため、一時的な対処でファイルサイズを減らすのではなく、200MBを超えても安定してリリースできるようにする方法を選択しました。

制限を超えてアプリをリリースする手段

Androidではファイルサイズの制限を超えてアプリをリリースするための手段として、 Play Asset Delivery (PAD)Play Feature Delivery があります。

Play Asset Delivery (PAD)

アセットのダウンロード方法とタイミングをカスタマイズでき、Google Play Consoleの標準の制限である200MBを超えるアプリの配信ができます。

アプリのサイズを最適化して Google Play のアプリのサイズ上限内に収める

アプリ コンポーネント アプリのダウンロード サイズの上限
ベース モジュール 500 MB
個々の機能モジュール 500 MB
個々のアセットパック 1.5 GB
すべてのモジュールとインストール時のアセットパックの合計 4 GB
オンデマンドまたは fast-follow で配信されたアセットパックの合計 30 GB

補足: Googleのドキュメントでは各モジュールの上限は500MBとなっていますが、PADを導入していない場合は200MBを超えるとGoogle Play Consoleのアップロードでエラーになりました

圧縮後のアプリの合計ダウンロードサイズは34GBまで許容されます。

Play Feature Delivery

アセットやコードを含むモジュールを、配信タイプに応じて分割配信できる仕組みです。 デバイス条件による配信制御や、ユーザーによる事後アンインストールを実現可能です。

  • 分離したいのはアセットだけでKotlinのコードを含めたいわけではない
  • 全ユーザーにアセットをバンドルしたく、デバイス条件による出し分けや事後アンインストールは不要
  • できるだけ低コストで対応したい

これらの要件から、Play Feature DeliveryではなくPADを選択しました。

Play Asset Delivery (PAD) の導入

アセットのダウンロードタイミング

種類 タイミング
install-time アプリのインストールと同時
fast-follow アプリのインストール後、バックグラウンドで開始
on-demand アプリの実行中、任意のタイミング

アプリの要件から、インストール時にすべてのアセットがバンドルされている必要があるため、 install-time を選択しました。

1. アセット用モジュールの追加

アセットのみを持つモジュールのため、 assetpack という名前のモジュールを追加しました。

// assetpack/build.gradle.kts
plugins {
    id("com.android.asset-pack")
}

assetPack {
    packName.set("assetpack")
    dynamicDelivery {
      // `install-time` , `fast-follow` , `on-demand` のいずれかを指定
      deliveryType.set("install-time")
    }
}
// settings.gradle.kts
rootProject.name = ...
include(
    ":app",
    ":assetpack",
    ...
)

2. アプリ本体に依存を追加

通常、モジュールを新規追加する場合は dependencies ブロックに implementation(project(":module_name")) のように追加します。 アセット用モジュールは android ブロックに assetPacks を追加します。

// app/build.gradle.kts
android {
  ...

  // `+= listOf(...)` で複数のアセット用モジュールを追加することも可能
  assetPacks += ":assetpack"

  ...
}

3. アセット用モジュールにアセットファイルを移動

アセット用モジュールの src/main/assets ディレクトリにアセットファイルを移動します。

参考 on-demand の場合

on-demand を指定した場合、アセットのダウンロード実行をコードでリクエストする必要があります。

val assetPackManager = AssetPackManagerFactory.getInstance(context)
assetPackManager.fetch(listOf("{packName}"))

まとめ

ファイルサイズの大きなAndroidアプリをリリースするために Play Asset Delivery (PAD) を使用しました。 Kotlinのコードを変更することなく、新規のモジュールを追加し、依存を設定、アセットファイルを移動するだけで対応が完了しました。 同じような課題に直面している方の参考になれば幸いです。

参考

We are hiring!

エムスリーでは、臨床ポケットアプリをはじめ様々なアプリを開発しています。もし興味がありましたらお気軽にお問い合わせください!

jobs.m3.com