apk瘦身;如何縮小體積呢?這篇文章來教你

前言

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

目錄

  • apk的結構
  • 圖片壓縮
    • 導入矢量圖
    • 適配問題
    • Tint 着色器
  • 動態庫移除
    • so庫的相關知識點
    • ABI
  • 結束語

apk的結構

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

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 內容。打包工具將 xml 內容編譯成二進制形式並壓縮。這些內容包含了語言字符串和styles,還包含了那些內容雖然不直接存儲在resources.arsc文件中,但是給定了該內容的路徑,比如佈局文件和圖片。所以又叫 資源映射表
  • AndroidManifest.xml: 包含了主要的Android配置文件。這個文件列出了應用名稱、版本、訪問權限、引用的庫文件。該文件使用二進制 xml 格式存儲。(譯註:該文件還能看到應用的minSdkVersion, targetSdkVersion等信息)

好的,現在我們已經知道apk到底是個什麼東東了,接下來我們開始一步步對這些內容進行瘦身處理。

圖片壓縮

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

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

在這裏插入圖片描述

明明只是一種圖片,而我們卻因爲大小和顏色,需要這樣的一組,顯然很佔大小,那有沒有什麼方式優化下呢?

答案是有的。

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

導入矢量圖

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

在這裏插入圖片描述

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

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

-d 指定svg文件所在目錄
-o 輸出android vector圖像目錄
-h 設置轉換後svg的高
-w 設置轉換後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去設置,如下:

在這裏插入圖片描述

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

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

在這裏插入圖片描述在這裏插入圖片描述
然後就可以直接使用了,如下:
在這裏插入圖片描述
總的來說使用Tint找色器去修改矢量圖的顏色還是蠻簡單的吧。

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

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

動態庫移除

so庫的相關知識點

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

那我們爲什麼要把so文件分別放在armeabi、arm64-v8a、armeabi-v7a、x86、x86_64這些文件中呢?

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

ABI

ABI 是應用程序二進制接口簡稱(Application Binary Interface),定義了二進制文件(尤其是.so文件)如何運行在相應的系統平臺上,從使用的指令集,內存對齊到可用的系統函數庫。在Android 系統上,每一個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 的指令集動態轉碼工具,實現 對 arm .so 的兼容,再考慮 x86 1% 以下的市場佔有率,x86 相關的兩個 .so 也是可以忽略的
  • armeabi:ARM v5 這是相當老舊的一個版本,缺少對浮點數計算的硬件支持,在需要大量計算時有性能瓶頸
  • armeabi-v7a:ARM v7 目前主流版本
  • arm64-v8a:64位支持

所以現在我們一般只要在項目的build.gradle中適配ARM v7就行了,如下:
在這裏插入圖片描述

結束語

如果你的技術提升遇到瓶頸了,或者缺高級Android進階視頻學習提升自己,這有大量大廠面試題爲你面試做準備!
點擊Android 學習,面試文檔,視頻收集大整理獲取

未完待續。。。

好的,今天我們就暫時介紹到這兒,瘦身之旅長路漫漫,還有的方式我們下次分享。
如果喜歡本文可以關注我們的官方賬號,第一時間獲取資訊。
你的關注是對我們更新最大的動力~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章