APK壓縮so文件

先描述一下結(jié)論:

android:extractNativeLibs = true時(shí),gradle打包時(shí)會(huì)對(duì)工程中的so庫(kù)進(jìn)行壓縮,最終生成apk包的體積會(huì)減小。
但用戶在手機(jī)端進(jìn)行apk安裝時(shí),系統(tǒng)會(huì)對(duì)壓縮后的so庫(kù)進(jìn)行解壓,從而造成用戶安裝apk的時(shí)間變長(zhǎng)。

關(guān)于android:extractNativeLibs默認(rèn)值設(shè)定方面,若開(kāi)發(fā)人員未對(duì)android:extractNativeLibs進(jìn)行特殊配置:

  • minSdkVersion < 23 或 Android Gradle plugin < 3.6.0情況下,打包時(shí) android:extractNativeLibs=true;
  • minSdkVersion >= 23 并且 Android Gradle plugin >= 3.6.0情況下,打包時(shí)android:extractNativeLibs=false;

一、起因

偶然發(fā)現(xiàn),使用AndroidStudio將同一Module分別打包為aarapk,兩者占用的磁盤(pán)空間差距巨大:
打包為aar,占用磁盤(pán)空間4.4M;打包為apk,占用磁盤(pán)空間為11.7M;

使用AndroidStudio中 apkanalyzer 對(duì)比分析,兩種打包方式so庫(kù) Rwa File Size 差距較大,但兩者的Download Size 大小完全一致:
打包為aar,so庫(kù)Rwa File Size為3.4M;打包為apk,so庫(kù)Rwa File Size為8.2M;
打包為aar,so庫(kù)Download Size為3.3M;打包為apk,so庫(kù)Download Size為3.3M;

兩種打包方式 apkanalyzer 對(duì)比分析如下:

打包為aar
打包為apk

兩種打包方式Rwa File SizeDownload Size 差距較大,那Raw File SizeDownload Size又是如何定義的呢?

二、Raw File Size & Download Size

官方 view_file_and_size_information: 描述如下:

APK Analyzer shows raw file size and download file size values for each entity, as shown in figure 1\. Raw File Size represents the unzipped size of the entity on disk while Download Size represents the estimated compressed size of the entity as it would be delivered by Google Play. The % of Total Download Size indicates the percentage of the APK's total download size the entity represents.

翻譯后:

APK Analyzer 展示每個(gè)實(shí)體的 Raw File Sizedownload file size
Raw File Size 代表對(duì)應(yīng)實(shí)體在磁盤(pán)上未進(jìn)行壓縮的大?。?br> Download Size 代表對(duì)應(yīng)實(shí)體在Google Play中,預(yù)估的壓縮后的大??;
% of Total Download Size 代表對(duì)應(yīng)模塊實(shí)體,在Download Size總大小中所占百分比。

View file and size information

看到這里,懷疑:

打包為aar時(shí),AndroidStudio對(duì)Module中的so庫(kù)進(jìn)行了壓縮;但打包為apk時(shí),未對(duì)Module中的so庫(kù)進(jìn)行壓縮。

三、android:extractNativeLibs

查詢相關(guān)資料,發(fā)現(xiàn)文章Android APK Raw File Size vs Download Size:
文章中提到:
打包APK時(shí),是否對(duì)so庫(kù)進(jìn)行壓縮的控制屬性為 android:extractNativeLibs

Android APK Raw File Size vs Download Size

AndroidManifest.xmlextractNativeLibs屬性使用方式:

<application
    android:extractNativeLibs="true">
</application>

3.1、android:extractNativeLibs = true

android:extractNativeLibs = true,進(jìn)行apk打包時(shí),AndroidStudio會(huì)對(duì)Module中的so庫(kù)進(jìn)行壓縮,最終得到的apk體積較小。

  • 好處是:用戶在應(yīng)用市場(chǎng)下載和升級(jí)時(shí),因?yàn)橄牡牧髁枯^小,用戶有更強(qiáng)的下載和升級(jí)意愿。
  • 缺點(diǎn)是:因?yàn)閟o是壓縮存儲(chǔ)的,因此用戶安裝時(shí),系統(tǒng)會(huì)將so解壓出來(lái),重新存儲(chǔ)一份。因此安裝時(shí)間會(huì)變長(zhǎng),占用的用戶磁盤(pán)存儲(chǔ)空間反而會(huì)增大。

3.2、android:extractNativeLibs = false

android:extractNativeLibs = false,進(jìn)行apk打包時(shí),AndroidStudio不會(huì)對(duì)Module中的so庫(kù)進(jìn)行壓縮,最終生成的apk體積較大。

  • 好處是:用戶安裝后,直接使用/data/data/your.app.package/lib路徑下的so,沒(méi)有額外的so復(fù)制操作,相對(duì)于android:extractNativeLibs = true而言,節(jié)省用戶磁盤(pán)存儲(chǔ)空間;

3.3、結(jié)論

android:extractNativeLibs = true的設(shè)定還是利大于弊的。

設(shè)置為true可以工程中的so庫(kù)進(jìn)行壓縮,最終減小生成的apk包大小。至于安裝應(yīng)用時(shí),因so庫(kù)解壓縮而造成的安裝時(shí)間增長(zhǎng),相對(duì)于帶來(lái)的好處(提高應(yīng)用市場(chǎng)用戶的下載和升級(jí)意愿)而言,我認(rèn)為是可接受的。

四、android:extractNativeLibs默認(rèn)值

android:extractNativeLibs官方API描述如下:

android:extractNativeLibs官方API描述

從android:extractNativeLibs官方API描述中可以了解到:

  • 源碼中 android:extractNativeLibs默認(rèn)值為true;
  • 編譯器Android Gradle plugin 3.6.0 或更高版本,android:extractNativeLibs默認(rèn)值為false;

但真的是這樣嗎?一起來(lái)探究一下。

4.1、源碼中extractNativeLibs默認(rèn)設(shè)定

從Android 6.0(API 23)開(kāi)始,Android frame源碼中PackageParser.java在讀取android:extractNativeLibs屬性值時(shí),默認(rèn)值為true;

對(duì)應(yīng)的源碼路徑:frameworks/base/core/java/android/content/pm/PackageParser.java

if (sa.getBoolean(
        com.android.internal.R.styleable.AndroidManifestApplication_extractNativeLibs,
        true)) {
    ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS;
}

4.2、Android Gradle plugin 3.6.0 或更高版本

編譯器Android Gradle plugin 3.6.0 或更高版本,在構(gòu)建應(yīng)用時(shí)會(huì)默認(rèn)將 extractNativeLibs 設(shè)置為 false。

通過(guò)觀察編譯后生成的AndroidManifest.xml文件,發(fā)現(xiàn) gradle 插件設(shè)置默認(rèn)值為false,是通過(guò)在處理AndroidManifest.xml文件的時(shí),在其中自動(dòng)插入 android:extractNativeLibs=“false"來(lái)實(shí)現(xiàn)的。
由于 android:extractNativeLibs 這個(gè)屬性是在Android 6.0(API 23)引入的,因此如果項(xiàng)目配置 中minSdkVersion < 23 的話,gradle 插件不會(huì)自動(dòng)插入android:extractNativeLibs=“false"。

4.3、結(jié)論

開(kāi)發(fā)人員在進(jìn)行apk打包時(shí),若未對(duì)android:extractNativeLibs進(jìn)行特殊配置:

  • minSdkVersion < 23 或 Android Gradle plugin < 3.6.0,打包時(shí) android:extractNativeLibs=true;
  • minSdkVersion >= 23 并且 Android Gradle plugin >= 3.6.0,打包時(shí)android:extractNativeLibs=false
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容