1
2

More than 1 year has passed since last update.

APKのサイズを約80%削減した

Last updated at Posted at 2021-11-14

TL;DR

  • 結果
# ls -l *.apk
-rwxrwxrwx 1 kabocha kabocha 293997572 Nov 14 20:22 original.apk*
-rwxrwxrwx 1 kabocha kabocha 289364774 Nov 14 20:54 minifyEnabled_shrinkResources.apk*
-rwxrwxrwx 1 kabocha kabocha  97902257 Nov 14 21:34 abiFilters.apk*
-rwxrwxrwx 1 kabocha kabocha  49605621 Nov 14 22:48 extractNativeLibs.apk*     # 最終結果

(49605621/293997572)*100 ≒ 16.87...

  • app/build.gradle で,ndk.abiFilters を指定
android {
    defaultConfig {
        // arm64のみサポートする.
        ndk {
            abiFilters 'arm64-v8a'
        }
  • AndroidManifest.xmlapplication.android:extractNativeLibstrue に指定
  • app/build.gradle で,buildTypes.minifyEnabled, buildTypes.shrinkResourcestrue に指定

APKサイズがでかいんじゃ

かぼちゃです.普段,Androidの組み込みエンジニアとして働いています.

Google Play Storeに新規で公開するには,Android App Bundle でないといけなくなりましたので,そろそろAPK自体使われなくなりそうな風潮もありますが,組み込みAndroidにおいては,プリインストールする際などには,ソースコードもしくは,APKが必要です.

さて,お仕事の中で,取り込んでいるAARやライブラリの都合で1つのAPKだけで,300MB近いものをプリインストールしなければならない事態になりました.
もちろん,技術的には問題ありませんが,例えばFOTAでそのアプリを更新するとなると,その分の差分が大きくなりますので,ユーザーが負担する通信コストも肥大化してしまいます.
(Androidの差分FOTAは非常に優秀なので,そこまで大きくはなりませんが...)

こういった背景から,このでかすぎるAPKのサイズを,小さくしていく中で,特に効果的だったものを書かせていただいています.
なお,今回は実装の変更等はせず,設定周りだけを修正していますので,取り込みやすいかもしれません.また前提として,今回は Android StudioでGradleを使って,ビルド・開発するものとします.

ndk.abiFilters (およそ 67% 削減)

NDKで開発されたことがある人は,ご存知かもしれません.Android Developerから引用すると,

Gradle はデフォルトでは、NDK がサポートするアプリケーション バイナリ インターフェース(ABI)の個々の .so ファイルにネイティブ ライブラリをビルドし、それをすべてアプリにパッケージ化します。Gradle を使ってネイティブ ライブラリの特定の API 設定のみビルドしてパッケージ化したい場合は、下記に示すように、モジュール レベルの build.gradle ファイル内で ndk.abiFilters フラグを使って指定できます。

とあります.つまり特に指定とかをしていない場合だと,エミューレータでも動くように,x86_64 向けなどの .soライブラリをビルドして,APKに入れてしまっているわけですね.
一般的なAndroidデバイスだと,arm系がほとんどだと思いますので,削れそうです.(Google Play Store等に公開するときは怒られる気がします.)
まして,私のような組み込みAndroidの場合,極端な話動作保証をするハードウェアが限られてきますので,不要な構成をビルドする理由はなさそうです.
arm64-v8a のみを対象にしてビルドしてみると,適応前のおよそ33%にまでバイナリサイズを抑えることができました.

およそ290MB → およそ98MB

参考,引用

application.android:extractNativeLibs (およそ 50% 削減)

Android Developerから引用すると

パッケージ インストーラがネイティブ ライブラリを APK からファイル システムに抽出するかどうかを指定します。false に設定した場合、ネイティブ ライブラリは、ページ アライメントを行ったうえで、圧縮せずに APK 内に保存する必要があります。実行時にリンカーが直接 APK からライブラリをロードするため、コードを変更する必要はありません。

とあります.いかにも,デフォルト true のような記述になっていますが,Android Gradle プラグイン 3.6.0 のリリース を確認すると,デフォルトで false にしているという記述がありました.これも,APKサイズが大きくなってしまう原因となっているようなので,有効にしました.

およそ98MB → およそ50MB

参考,引用

buildTypes.minifyEnabled, buildTypes.shrinkResources (およそ 数MB 削減)

説明はDeveloperサイトで行われていますので,割愛します.

参考

終わりに

結果として,もともとの15%近いAPKサイズにまで小さくすることができました.
もちろん,APKに占める割合にリソースファイルが大多数のときなどは,今回のアプローチだけでは難しいですが,一助になれば幸いです.

1
2
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
1
2