apk ファイルと aab ファイルについて調べてみた


# TL;DR

App Bundle で問題なく開発できます。ていうかこれからリリースする人は AppBundle 推奨って Google も言ってる。

# 概要

かつて社内用に調査してまとめたものが褒められてうれしかったので公開してゆくスタイル。

# Android アプリのパッケージ形式

Android アプリのパッケージ形式には 2 つのタイプがある。

- .apk
- .aab

難読化を施した場合、.apk ファイルは mapping.txt を取得しておかないと難読化を解除できない。
一方で .aab は mapping.txt の内容をすでに含んでいるという話がある。

アプリをリリースする際には .aab で行うように Google が推奨しているが、__開発時にエラーログを読みやすくするためにはどちらの方式が良いか__ を決めるために、どちらのファイル形式が良いか調査を行った。

# 調査内容

##  Google Play ストアにアップロードできる形式の種類

- APK ファイル (.apk)
-  [APK 拡張ファイル](https://developer.android.com/google/play/expansion-files?hl=ja) 
- App Bundle ファイル (.aab)
    - 分割 APK ファイル

### APK ファイルとは

- ビルドしたバイナリ等のファイルを ZIP でアーカイブしたもの。
- .zip に拡張子を変更すれば ZIP で伸長できる。 
- 参考: 
  - [Wikipedia: APK (ファイル形式) ](https://ja.wikipedia.org/wiki/APK_(%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%BD%A2%E5%BC%8F))
  - [Qiita の記事](https://qiita.com/kasaharu/items/900fc937be80d87090ce)
- 難読化をスタックトレース時に解除するときには mapファイルが必要。

### APK 拡張ファイルとは

- 公式：https://developer.android.com/google/play/expansion-files?hl=ja
- BLOB を Google Play ストアに登録するためのファイル
    - BLOB: Binary Large Object : 画像・音声・動画等、サイズが比較的大きく、構造化されていないファイル。DBMS に登録可能なデータ型。
    - APK ファイルの場合、100MB までという制限があるため、それを回避するためのもの
    - APK ファイル以外に 2 つ添付することを認められている。
        - メイン拡張ファイル：アプリで必要となる追加リソースの主要な拡張ファイル
        - パッチ拡張ファイル：メイン拡張ファイルの小規模アップデート用。省略可能。
- アップロードする形式は自由。送ると Google Play の方でよしなにやってくれる（はず）
    - [JOBB](https://developer.android.com/studio/command-line/jobb?hl=ja) ツールを使うと、下記ができるようになる
        - ファイルの圧縮・伸長
        - ファイルの暗号化
- APK 拡張ファイルを使うためには、Android アプリ内で共有ストレージに保存するようにしなければならない。

> Google Play が拡張ファイルをデバイスにダウンロードすると、ファイルはシステムの共有ストレージに保存されます。正しい動作が確実に行われるように、拡張ファイルの削除、移動、名前変更は行わないでください。アプリ自体が Google Play からダウンロードしなければならない場合は、拡張ファイルもまったく同じ場所に保存してください。

- APK 拡張ファイルは、共有ストレージに保存されるため、外部から読み取られた場合を考えた設計が必要である。

> 注意: APK ファイルとは異なり、共有ストレージに保存されているファイルはすべて、ユーザーや他のアプリで読み取られる可能性があります。

### App Bundle ファイルとは

- Google 公式の定義　[Android App Bundle について](https://developer.android.com/guide/app-bundle?hl=ja)

> Android App Bundle は、アプリのコンパイル済みコードとリソースがすべて含まれた公開形式です。ただし、APK の生成と署名は Google Play が行います。

- APK ファイルを用いる場合よりも圧縮ダウンロードサイズの制限が緩い。ただし、APK 拡張ファイルの併用はできない。

> Android App Bundle を使用した圧縮ダウンロード サイズの制限は 150 MB になりました。App Bundle と APK 拡張ファイルの併用はできません。

- デバイスにデプロイできないと[公式の記事](https://developer.android.com/guide/app-bundle#get_started)にはあるが、意味がよくわからない:weary: 
    - [この記事](https://developer.android.com/guide/app-bundle/test?hl=ja#deploy-using-studio) にある通り、App Bundle の Debug ビルドは、Android Studio が APK を接続済みデバイスにデプロイできるので、今までと使い勝手はほぼ変わらない。
    - 前項の記事によれば、Google Play と同じツールを使って App Bundle をビルドする。

> IDE と Google Play は同じツールを使用して APK を抽出し、デバイスにインストールするため、このローカルテスト戦略で以下について確認できます。
> 
> - アプリを App Bundle としてビルドできる。
> - IDE が App Bundle から対象のデバイス設定向けに APK を抽出できる。
> - 機能モジュールに分割した機能が、アプリのベース モジュールで利用できる。
> - アプリが期待どおりに対象デバイスで機能する。

- aab ファイルのデバイスへのインストールは [bundletool](https://developer.android.com/studio/command-line/bundletool?hl=ja)を使えばできる。
- または、テストトラックへアップロードすることで App Bundle ファイルをテストすることができる。
- App Bundle を利用した場合、App Bundle 内部から必要な情報を取得できるので、mapファイルのアップロードは不要。
    - [クラッシュのスタック トレースの難読化を解除する、シンボリケートする](https://support.google.com/googleplay/android-developer/answer/9848633?hl=ja)

![pasted-2021.04.07-17.35.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174232/de14a7de-399c-bfb3-2c17-22bd5d134057.png)
[図 1.1 つのベース モジュール、2 つの機能モジュール、2 つの Asset Pack が含まれる Android App Bundle のコンテンツ](https://developer.android.com/images/app-bundle/aab_format-2x.png)を引用

### 分割 APK とは

https://developer.android.com/guide/app-bundle#split_apks

- 最適化されたアプリケーションを提供するための基本的なコンポーネントのこと
- Android 5.0（API レベル 21）以上で利用できるメカニズムである。
- 共通のコードやリソースにアクセスできる複数の分割 APK をインストールし、1 つのインストール済みアプリとしてデバイスに表示できる。
- Android 4.4（API レベル 19）以前を搭載するデバイスは、分割 APK のダウンロードとインストールに対応していないため、代わりに Google Play がデバイスに単一の APK を配信する。
    - 「マルチ APK」と呼ばれ、デバイスの構成に合わせて最適化されている。
- これらの APK をご自分でビルドする必要はなく、Android Studio でビルドした署名済みの 1 つの App Bundle から、Google Play が APK をビルドする。

![pasted-2021.04.07-17.34.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174232/9ed6dae5-b296-ac0f-acd5-6c7cfa0fc896.png)

[図 1.分割 APK を使用して配信されるアプリの依存関係ツリー](https://developer.android.com/images/app-bundle/apk_splits_tree-2x.png)を引用

## アプリへの署名

- [公式：アプリへの署名](https://developer.android.com/studio/publish/app-signing?hl=ja)
    - Android Studio を使わない場合は、apksigner を用いる。

### アプリ署名のバージョンについて

- [公式：APK 署名方式](https://source.android.com/security/apksigning#schemes)

> Android では、次の 3 つのアプリ署名方式がサポートされています。
> 
> v1 スキーム: JAR 署名に基づく
> v2 スキーム: Android 7.0 で導入された APK 署名スキーム v2。
> v3 スキーム: Android 9 で導入された APK 署名スキーム v3。
> 互換性を高めるには、最初に v1、次に v2、その次に v3 というように、すべてのスキームでアプリに署名します。

- 古くから作り続けられている Android アプリでは、V1, V2 で署名しており、V3 での署名をしていないものもあるだろう。
- しかし、公式のページから読み取れるのは、Google が推奨しているのは全てのスキームでアプリに署名することであるらしい。
- 参考: https://qiita.com/ntsk/items/ce655a804654dac33d73

# ローカルデバッグ時のログ取得

Android Studio の __Build > Build Bundle(s) / APK(s)__ から __Build Bundle(s)__ を選択する。
このとき、Debug 用の Build Variant を選択していないと Android Studio に怒られるので、あらかじめ設定しておく。
最初にビルドする時は、どのタイプのビルドを行うか聞かれるので __APK from app bundle__ を選択する。
参考： https://developer.android.com/studio/run/rundebugconfig?hl=ja#android-application

あとは普通にビルドしてデバッグすれば、実機接続していても起動するし、Console もみられるし、Logcat も確認できる。

# DeployGate

aab でのアップロードは可能。
参考: https://deploygate.zendesk.com/hc/ja/articles/360011088499-Android-App-Bundle-%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E6%A9%9F%E8%83%BD

# おわりに

aab で Google Play Console にアップロードして署名などもできるようにしておくと、いろいろと手間が省けるし、リソースの最適化などもしてくれるので、これからは .aab 形式で Google の審査に出していくことが主流になるのだろうなと思った。