apk瘦身之旅

我們完成一個app后,都需要生成一個apk,然后上線,而apk的大小也一定程度的影響了用戶是否愿意下載你的這個app,所以也就有了apk瘦身這門藝術。

目錄

  • apk的結(jié)構

  • 圖片壓縮

    • 導入矢量圖

    • 適配問題

    • Tint 著色器

  • 動態(tài)庫移除

    • so庫的相關知識點

    • ABI

  • 結(jié)束語

apk的結(jié)構

既然要對一個apk瘦身,首先我們就得知道apk格式的文件內(nèi)容。實際上一個apk文件就是一個zip包,我們只需要將后綴改為zip,然后進行解壓就可以看到里面的內(nèi)容了。下面我們來看下它里面的文件以及作用:

apk包含以下目錄:

  • assets/: 包含了應用的資源,這些資源能夠通過AssetManager對象獲得。

  • lib/: 包含了針對處理器層面的被編譯的代碼。這個目錄針對每個平臺類型都有一個子目錄,比如armeabi, armeabi-v7a, arm64-v8a, x86, x86_64和mips。

  • res/: 包含了沒被編譯到resources.arsc的資源。

  • META-INF/: 包含CERT.SF和CERT.RSA簽名文件,也包含了MANIFEST.MF文件。(譯注:校驗這個APK是否被人改動過)

apk包含以下文件:

  • classes.dex: 包含了能被Dalvik/Art虛擬機理解的 dex 文件格式的類。

  • resources.arsc: 包含了被編譯的資源。該文件包含了res/values目錄的所有配置的 xml 內(nèi)容。打包工具將 xml 內(nèi)容編譯成二進制形式并壓縮。這些內(nèi)容包含了語言字符串和styles,還包含了那些內(nèi)容雖然不直接存儲在resources.arsc文件中,但是給定了該內(nèi)容的路徑,比如布局文件和圖片。所以又叫 資源映射表

  • AndroidManifest.xml: 包含了主要的Android配置文件。這個文件列出了應用名稱、版本、訪問權限、引用的庫文件。該文件使用二進制 xml 格式存儲。(譯注:該文件還能看到應用的minSdkVersion, targetSdkVersion等信息)

好的,現(xiàn)在我們已經(jīng)知道apk到底是個什么東東了,接下來我們開始一步步對這些內(nèi)容進行瘦身處理。

圖片壓縮

我們都知道,一個apk會使用大量的圖片,如果圖片這塊能夠壓縮下,那效果還是非??捎^的。

如下圖,我們在項目中經(jīng)常會用到這樣的套圖。

明明只是一種圖片,而我們卻因為大小和顏色,需要這樣的一組,顯然很占大小,那有沒有什么方式優(yōu)化下呢?

答案是有的。

谷歌的AS為我們提供了一個名為 Vector Asset Studio 的工具,可以幫助我們添加內(nèi)置Material圖標以及將本地的SVG(Scalable Vector Graphics 可縮放矢量圖)等格式作為矢量圖資源導入到項目中,會在drawable目錄下生成一個根節(jié)點為vector的xml文件,而且矢量圖的大小也更小,是不是非常棒??!那下面我們來看看怎么實現(xiàn)的。

導入矢量圖

首先我們在AS中運行Vector Asset Studio,步驟是:右鍵點擊你工程中的res文件夾,然后選擇 New --> Vector Asset,此時會彈出下面對話框,選擇圖中標記的對應操作即可導入內(nèi)置Material圖標或者SVG矢量圖。

但是上面這種方式只能一張張導入圖片,顯然很麻煩。那有沒有更好的方式了?實際上我們之所以要用這個工具導入svg圖片,而不是直接將svg圖片復制到drawable中,是因為安卓不支持svg,需要工具轉(zhuǎn)換下,所以我們可以使用svg2vector這個第三方庫進行批量轉(zhuǎn)換,然后直接復制到drawable中即可,轉(zhuǎn)換命令如下:

java -jar svg2vector-cli-1.0.0.jar -d . -o a -h 20 -w 20

-d 指定svg文件所在目錄 -o 輸出android vector圖像目錄 -h 設置轉(zhuǎn)換后svg的高 -w 設置轉(zhuǎn)換后svg的寬

適配問題

因為矢量圖是在Android 5.0(API21)才開始支持的,所以這個地方我們還需要適配下。如果不適配,你的最小minSdkVersion版本又小于21,則會自動在每個drawable目錄下生成對應的png圖片,反而會使apk包變大,所以這里一定要注意了。我們有下面兩種方式進行適配:

方式一:生成 png 格式的圖片

這種方式是在drawable文件中生成對應的png,不過我們可以指定只生成哪幾個。例如如下配置

我們可以在項目的build.gradle中進行如下配置,即可在指定的drawable文件中生成對應的png格式圖片。

方式二:支持庫

還一種方式就是使用支持庫,支持庫的版本需要23.2或者更高,也是在項目的build.gradle中進行配置,如下:


這種適配方式使用圖片的時候,需要用 app:srcCompat 屬性,而不是 android:src,如下:

通過這個方式只是解決了不同大小需要多張圖片的問題,但是還需要有不同顏色的圖片。這個我們怎么處理呢?不要急,這個問題谷歌工程師也為我們準備了一個工具,它就是Tint著色器。

Tint 著色器

一般我們矢量圖都是使用黑色,然后由Tint著色器去修改顏色,直接在xml中使用即可,如下:

在java代碼中,我們可以通過DrawableCompat去設置,如下:

那如果想要實現(xiàn)按鍵效果,通過 Tint 也能實現(xiàn)嗎?答案是可以的。

首先我們需要創(chuàng)建兩個選擇器,一個是 drawable 選擇器,一個是 color 選擇器,如下:

然后就可以直接使用了,如下:

總的來說使用Tint找色器去修改矢量圖的顏色還是蠻簡單的吧。

通過矢量圖這個方式,我們就能夠減小使用圖片的總大小,從而減小apk的大小。

瘦身不是一蹴而就的,所以我們接著減。

動態(tài)庫移除

so庫的相關知識點

說到so庫,相信大部分人都有使用過,但是卻不知道它到底是什么。其實so庫就是由ndk編譯出來的動態(tài)庫。

那我們?yōu)槭裁匆裺o文件分別放在armeabi、arm64-v8a、armeabi-v7a、x86、x86_64這些文件中呢?

主要是因為我們的app運行在不同的手機中,而so庫是由c\c++編譯的,不是跨平臺的,所以不同平臺(不同CPU)需要使用不同的so庫。那不同的文件是什么意思呢?我們接著往下看。

ABI

ABI 是應用程序二進制接口簡稱(Application Binary Interface),定義了二進制文件(尤其是.so文件)如何運行在相應的系統(tǒng)平臺上,從使用的指令集,內(nèi)存對齊到可用的系統(tǒng)函數(shù)庫。在Android 系統(tǒng)上,每一個CPU架構對應一個ABI,即:armeabi,armeabi-v7a,arm64-v8a,x86,x86_64,mips,mips64。

ABI

Supported Instruction Set(s)

armeabi

ARMV5TE and later,Thumb-1

armeabi-v7a

armeabi,Thumb-2,VFPv3-D16,Other,optional

arm64-v8a

AArch-64

x86

x86(IA-32),MMX,SSE/2/3,SSSE3

x86_64

x86-64,MMX,SSE/2/3,SSE3,SSE4.1,SSE4.2,POPCNT

mips

MIPS32r1 and later

mips64

MIPS64r6

各版本分析如下:

  • mips / mips64:極少用于手機可以忽略

  • x86 / x86_64:x86 架構的手機都會包含由 Intel 提供的稱為 Houdini 的指令集動態(tài)轉(zhuǎn)碼工具,實現(xiàn) 對 arm .so 的兼容,再考慮 x86 1% 以下的市場占有率,x86 相關的兩個 .so 也是可以忽略的

  • armeabi:ARM v5 這是相當老舊的一個版本,缺少對浮點數(shù)計算的硬件支持,在需要大量計算時有性能瓶頸

  • armeabi-v7a:ARM v7 目前主流版本

  • arm64-v8a:64位支持

所以現(xiàn)在我們一般只要在項目的build.gradle中適配ARM v7就行了,如下:

結(jié)束語

好的,今天我們就暫時介紹到這兒,瘦身之旅長路漫漫,還有的方式我們下次分享。

未完待續(xù)。。。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

  • APK瘦身可以為我們帶來什么好處? 提高傳輸及編譯效率。無論是上傳應用商店還是公司內(nèi)部傳輸以及我們自己編譯,越小的...
    在心的末端閱讀 1,000評論 0 2
  • 隨著app的業(yè)務復雜度越來越高、資源文件越來越多,我們的app安裝包apk文件也就越來越大,而過大的apk文件往往...
    jackting閱讀 9,077評論 1 2
  • apk分析 讓我們在瘦身前先瞅一眼apk是什么,里面有啥:這里是用的工具是Android studio里,buil...
    劉喵喵嗷嗚閱讀 355評論 0 0
  • 了解Apk結(jié)構 APK 文件就是一個Zip格式的文件,其中包含構成應用的所有文件。這些文件包括 Java 類文件、...
    zcwfeng閱讀 431評論 0 2
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,857評論 28 54

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