APKをスリム化する方法
この質問で何を調べたいのですか?
- APK をスリム化する方法の実際のシナリオを理解していますか? APK をスリム化する方法によって引き起こされるシナリオを理解していますか?
調査すべき知識のポイント
- APKをスリム化してプロジェクトで使用する方法と基礎知識
候補者はどう答えるべきか
APK のサイズは、アプリの読み込み速度、メモリ サイズ、電力消費に大きな影響を与えます。一般に、ユーザーは APK サイズが大きすぎるアプリをダウンロードすることを好みません。特に、トラフィックと携帯電話のメモリが限られているユーザーにとって、APK が大きすぎると使用を妨げてしまうことが多いため、APK をスリム化する必要があります。
APK をスリム化したい場合は、まず APK の構造を理解する必要があります。APK がどのような部分で構成されているかを理解することによってのみ、目標を絞った方法で APK をスリム化することができます。
APK は主に次の部分で構成されます:
- META-INF/ :包含了签名文件
CERT.SF
、CERT.RSA
,以及 manifest 文件MANIFEST.MF
。 - assets/: リソース ファイルを保存します。これらのリソースはバイナリにコンパイルされません。
- lib/: 参照されるサードパーティ ライブラリがいくつか含まれています。
- resources.arsc:
strings
、styles
などの res/values/ 内のすべてのリソースが含まれます。その他resources.arsc
に含まれないリソース パス情報 (レイアウト ファイル、画像など)。 - res/:
resources.arsc
に保存されていないリソースが res に含まれます。 - classes.dex: dx コンパイル後に Android 仮想マシンが理解できる Java ソース コード ファイル。
- AndroidManifest.xml: これについては説明する必要はありません
Android Studio --> build --> Analyze APK を使用して、上記の各部分のファイル サイズを確認します。
以下の図に示すように、占有されるスペースは主に code、res、lib です。アセットにはファイルがないため、多くのスペースを占有しているようには見えません。実際、アセットに多くのファイルがある場合、資産を含めても、依然として多くのスペースを占有することになります。したがって、APK をスリム化する場合は、代码
、res
、lib
、assets
に主に焦点を当てます。 . 考慮すべき主な側面:
リソース ファイルの数とサイズを減らす
APK をスリム化する非常に簡単な方法は、リソース ファイルの数とサイズを減らすことであることを理解しておく必要があります。
無駄なリソースを削除する
未使用のリソースがあるかどうかを使用lint
検出res/
します。
ただし、一部のサードパーティ ライブラリでは、lint を使用しても検出できない場合があります。shrinkResources
を使用してライブラリ ファイル内の不要なリソースを削除し、proguard で使用してファイルを圧縮できます。コード
android {
// Other settings
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
未使用の予備リソースを削除します。たとえば、一部のサードパーティ ライブラリでは、国際化の問題により数十の言語がサポートされる場合がありますが、アプリケーションでは中国語のみをサポートする必要がある場合があります。この場合、resConfig
またはresConfigs
で解決します。
次のコードは、言語リソースを中国語のみをサポートするように制限する方法を示しています。
android {
defaultConfig {
...
resConfigs "zh"
}
}
リソースを最小限に抑えるライブラリを使用する
プロジェクトを開発する際、多くのサードパーティ ライブラリが使用されることがよくありますが、サードパーティ ライブラリは非常に大きい場合が多いため、どのように圧縮すればよいでしょうか?
-
ProGuard を使用してコードを圧縮し、
shrinkResources
で使用します。この方法については、上記のshrinkResources
の使用方法を参照してください。 -
ただし、ProGuard はライブラリ自体内の一部の未使用コードのみを圧縮できますが、ライブラリ自体は依然として他のサードパーティ ライブラリに依存している可能性があり、ProGuard はこれらのライブラリを効果的に削除できません。
多くのサードパーティ ライブラリでは、フル バージョン、合理化バージョン、特定の機能の特別バージョンなど、複数のバージョンが提供されています。必要な機能を含む最小バージョンのライブラリを選択するだけで済みます。 。もちろん、ソースコードを入手して必要な機能を自分で抽出できればそれに越したことはありません。
特定の画面密度のみをサポートします
Android は、さまざまな画面密度のデバイスをサポートしています。Android 4.4 以降では、ldpi、mdpi、tvdpi、hdpi、xhdpi、xxhdpi、xxxhdpi がサポートされています。 Android は非常に多くの画面密度をサポートしていますが、すべてをサポートする必要はなく、ニーズに基づいてサポートを選択できます。
描画可能なオブジェクトの使用
一部の単純な画像の場合は、画像を使用する代わりに Drawable XML
を使用できます。
リソースを再利用する
同じ画像をいくつかの類似した画像に再利用できます。
-
同じ形で色と影が異なる画像。Android 5.0 (API レベル 21) 以降では、
android:tint
、tintMode
Wait を使用できます。 Android 5.0 未満では、ColorFilter
を使用して調整できます。 -
同じ形と色で角度が異なる画像。
rotate
などを使用して角度を調整し、再利用効果を得ることができます。例:<?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_thumb_up" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="180" />
コードのレンダリング
カスタム ビューを使用して描画するなど、画像を使用する代わりにコードを通じてレンダリングすることもできます。写真の枚数も減り、APKも自然とスリムになりました。
PNGファイルを圧縮する
AAPT ツールは、ビルド プロセス中に、res/drawable/ フォルダー内の PNG 画像リソースに対してロスレス圧縮を自動的に実行します。たとえば、実際に 256 色以下しか必要としない場合、トゥルーカラー PNG イメージは 8 ビット パレット イメージ (PNG8) に変換できます。変換された画質は低下せず、使用するメモリが少なくなるだけです。
PNG と JPG を圧縮する
你可以使用pngcrush, pngquant 或 zopflipng来压缩PNG图片。
使用packJPG 或 guetzli 来压缩JPG图片。
WebP の使用
JPG や PNG 画像の代わりに WebP を使用できます。 WebP JPG と PNG の利点を維持しながら、圧縮率を高め、サイズを小さくすることができます。
注意事项:启动图标最好不要用WebP,因为谷歌商店只接受启动图片格式为PNG的APK。
ベクター グラフィックを使用する
ベクター グラフィックを使用して、解像度に依存しないアイコンやその他のスケーラブルなメディア ファイルを描画できます。ベクター画像を使用する場合、画面全体と同じくらい大きい鮮明な画像は 100 バイトのサイズだけで済みます。
ただし、ベクター グラフィックを使用するとシステムの描画に時間がかかるため、小さい画像に対してのみベクター グラフィックを使用することをお勧めします。
アニメーション画像にはベクター グラフィックを使用する
フレーム アニメーションの作成には使用しないでくださいAnimationDrawable
。フレームごとに 1 つの画像を使用すると、多くのスペースが必要になります。この時点では、AnimatedVectorDrawableCompat
を使用する必要があります。
不要な生成コードを削除する
自動生成されたコードの目的を必ず理解してください。たとえば、使用しない可能性のある大量のコードを自動的に生成するプロトコル バッファー ツールが多数あります。
列挙型の使用を避ける
単一の列挙により、APK サイズが 1.0 ~ 1.4 KB 増加する可能性があります。複雑なシステムや共有ライブラリの場合、これが合計するとかなりの APK サイズになる可能性があります。
可能であれば、 @IntDef
アノテーションと ProGuard
を使用して列挙型を削除し、整数に変換することを検討してください。この型変換により、列挙型の型安全性の利点が維持されます。
ローカルバイナリのサイズを削減する
APP がネイティブ コードと Android NDK を使用している場合、2 つの方法でコードを最適化して APK サイズを削減できます。
-
デバッグ シンボルを削除する
Android NDK で提供されるarm-eabi-strip
ツールを使用して、ネイティブ ライブラリ内の不要なデバッグ シンボルを削除します。 -
ローカル ライブラリの抽出を避ける
Android 6.0 より前では、ファイルは apk に圧縮されます。システムはアプリケーションをインストールするときに、so ファイルをデータ パーティションに解凍します。同じように、so ファイルのコピーが 2 つあり、1 つは apk に、もう 1 つはデータ領域にあり、2 倍のスペースを占有します。 Android 6.0 以降、AndroidManifest.xml で新しい属性を使用できるようになりました。次のように: この属性は、apk から so ファイルを解凍しないようにシステムに指示し、apk から直接 so ファイルを開くように System.loadLibrary 呼び出しを変更します。
<application android:extractNativeLibs=”false” ... >
APK の複数のライト バージョンを維持する
アプリには、地域情報や言語情報など、ユーザーがまったく使用しないコンテンツが多数含まれている場合があります。画面サイズや GPU テクスチャのサポートなどの要素に基づいて、APK のさまざまなバージョンを提供できます。ユーザーが APK をダウンロードすると、携帯電話の特性と設定に基づいて特定のバージョンの APK がダウンロードされるため、ユーザーはまったく必要のないコンテンツをダウンロードすることはありません。
android {
...
splits {
//根据屏幕像素密度来创建多个APK
density {
enable true
//根据屏幕密度创建两个版本APK,"mdpi", "hdpi"
reset()
include "mdpi", "hdpi"
}
//根据手机cpu指令集分类创建多个APK
abi {
enable true
//创建 "x86", "x86_64"两个版本APK
reset()
include "x86", "x86_64"
}
}
}
APK をコンパイルして結果を見てみましょう。
上の図を分析すると、6 つの APK が生成されたことがわかります。なぜ 6 つなのでしょうか?
答え:
まず、画面密度には 3 つのバージョンがあります (mdpi
、x86_64
、gralde はすべての画面密度リソースを含むデフォルト バージョンも生成します)。 、ABI 命令セットには 2 つのバージョンがあります (gralde のデフォルトのコンパイルでは、すべての ABI 命令セット バージョンを含む APK は追加されません。追加したい場合は、abi コード ブロックに universalApk true
を追加する必要があります) )を合わせて6種類になります。各 APK には、対応するリソースのみが含まれます。たとえば、 app-hdpiX86-debug.apk
には、 hdpi
ライブラリと X86
の画面密度のリソースのみが含まれます。ファイル。
携帯電話の CPU 命令セットが x86 で、画面密度が HDPI の場合は、 app-hdpiX86-debug.apk
やっと
Android の面接の質問をまとめました。上記の面接の質問に加えて、[Java の基本、コレクション、マルチスレッド、仮想マシン、リフレクション、ジェネリックス、同時プログラミング、Android の 4 つの主要コンポーネント、非同期タスクとメッセージ メカニズム、UI 描画、パフォーマンス チューニング、SDN、サードパーティ フレームワーク、デザイン パターン、Kotlin、コンピューター ネットワーク、システム起動プロセス、Dart、Flutter、アルゴリズムとデータ構造、NDK、H. 264、H.265。オーディオ コーデック、FFmpeg、OpenMax、OpenCV、OpenGL ES]