そのため、ファイルごとのパッチは、圧縮されていないデータで検出された差分に基づきます。パッチの生成にあたって、まず古いファイルと新しいファイルの両方を解凍し、差分を計算します(ここでは、まだ bsdiff を利用しています)。次に、パッチを適用するため、古いファイルを解凍して圧縮されていないコンテンツに差分を適用し、新しいファイルを再圧縮します。その際に、端末上の APK が Play Store 上の APK とバイト単位で完全に一致していることを確認する必要があります(この理由については、APK 署名スキーマ v2 をご覧ください)。

新しいファイルの再圧縮には、2 つの問題があります。1 つ目の問題は、Deflate の設定によって Deflate の出力が色々と変わることです。そもそも、圧縮の際にどのような設定が使われたのかはわかりません。2 つ目は、Deflate には多くのバージョンが存在しており、ユーザーの端末上にある Deflate が適切なバージョンか確認する必要があります。

幸運にも、Play Store のアプリを分析したところ、Play Store のほぼすべての Deflate コンテンツで、zlib(もっとも普及している Deflate ライブラリ)に基づいた、互換性がある最近のバージョンの Deflate が使われていることがわかりました。さらに、実質的に使われている設定は、デフォルト(level=6)と最大(level=9)の圧縮設定だけでした。

以上のことを踏まえると、元々の Deflate 設定を検出して再現できると言えます。つまり、データを解凍し、パッチを適用してデータを再圧縮し、元々アップロードされたものと まったく同じバイト列 を作ることができます。

ただしこの方式には、端末側で必要な処理能力が高くなるという欠点もあります。最近(たとえば、2015 年以降)の端末では、再圧縮には 1 メガバイトあたり 1 秒少しかかり、古い端末や能力が低い端末はさらに時間がかかります。現時点の分析によると、平均で、パッチのサイズが半分になるとパッチの適用(再圧縮を含めたファイルごとのパッチ適用)にかかる時間は倍になります。

今のところ、この新しいパッチ テクノロジーの利用は自動アップデートのみに制限しています。これは通常、夜間にスマートフォンが電源に接続され、ユーザーが使用していない可能性が高いときにバックグラウンドで行われるアップデートです。これによって、ユーザーが手動でアプリをアップデートする際に、いつもより長く待たなければならないという事態を回避しています。

ファイルごとのパッチ適用の効率性

以下に、すでにファイルごとのパッチ適用を使っているアプリのアップデートの例を示します。

アプリ
元のサイズ
以前の(bsdiff)パッチサイズ
(元のサイズに対する割合)
ファイルごとのパッチによるサイズ(元のサイズに対する割合)
71.1 MB
13.4 MB(-81%)
8.0 MB(-89%)
32.7 MB
17.5 MB(-46%)
9.6 MB(-71%)
17.8 MB
7.6 MB(-57%)
7.3 MB(-59%)
18.9 MB
17.2 MB(-9%)
13.1 MB(-31%)
52.4 MB
19.1 MB(-64%)
8.4 MB(-84%)
16.2 MB
7.7 MB(-52%)
1.2 MB(-92%)


免責事項: 現在、ファイルごとのパッチはバックグラウンドでのみ利用されており、インタラクティブなアップデートには利用されていないため、手動で「アップデート」を押した際に表示されるパッチサイズとは異なる場合があります。

データを節約してユーザー(そしてデベロッパー)をハッピーに

以上の変更は、10 億人以上の Android ユーザー コミュニティが、最小限のデータ量でアプリの定期アップデートを行えるように設計されています。一番の長所は、デベロッパーは何もする必要がないことです。このアップデートのサイズ削減は、無償で行われます。

技術的な詳細など、ファイルごとのパッチ適用についてさらに詳しく知りたい方は、Archive Patcher GitHub プロジェクトをご覧ください。ソースコードを含む情報を閲覧できます。ファイルごとのパッチ適用は、完全なオープンソースです。

APK サイズをさらに削減したいデベロッパーの方は、APK サイズ削減のための一般的な推奨事項もご覧ください。


Posted by Khanh LeViet - Developer Relations Team

例 1: APK の新しい「ダウンロード サイズ」の表示


例 2: APK の新しい「アップデート サイズ」の表示


ダウンロード サイズを減らすためのヒント

1. 正しいサイズ計測のための最適化: ユーザーは、ダウンロード サイズ(アプリのインストールやアップデートでどのくらいのバイトが転送されるか)やディスクサイズ(アプリがどのくらいのディスクを使用するか)を気にしています。このどちらもが元の APK ファイルサイズと同じではなく、相関性があるとも限らないことを知っておくことが重要です。


Chrome の例:
圧縮済みのネイティブ ライブラリ 未圧縮のネイティブ ライブラリ
APK サイズ 39 MB 52 MB(+25%)
ダウンロード サイズ(インストール) 29 MB 29 MB(変更なし)
ダウンロード サイズ(アップデート) 29 MB 21 MB(-29%)
ディスクサイズ 71 MB 52 MB(-26%)


Chrome では、APK のネイティブ ライブラリを圧縮していないので初回ダウンロード サイズは同じですが、Google Play ではダウンロード用の圧縮が既に行われているため、APK のサイズは増加しています。未圧縮ファイルでは差分の効率が上がっているためアップデート サイズが減少し、圧縮済みネイティブ ライブラリをコピーする必要がなくなっているためディスクサイズも減少しています。

2. APK サイズの減少: 使用されていないリソースやコードなど、不要なデータを APK から削除します。

3. APK の構成要素のサイズを減らすことによる最適化: たとえば、JPEG ではなく WebP を使用するなど効率的なファイル形式を使ったり、未使用コードを削除するために Proguard を使用したりします。
APK サイズの削減についての詳細情報はこちらをご覧ください。また、I/O 2016 セッション「アプリをダイエットする」を見て、Wojtek Kaliciński がどのように APK サイズを削減しているかを学ぶこともできます

Posted by Yoshifumi Yamaguchi - Developer Relations Team