Android安裝包大小優化


安裝包的構成

1 assets

assets目錄可根據應用需求存放任何文件夾架構,比如配置文件,資源文件,圖片資源,這些文件的內容再程序運行過程中可以通過AssetManager類獲得。和res不同在於,res下的文件會在R文件中生成對應的資源ID,assets不會生成ID

2 lib

存放C/C++寫的庫文件,4個類型:ARM、ARM-v7a、MIPS、X86

目前的移動設備大部分是基於ARM或者ARM-v7a架構的,X86和MIPS架構的移動智能終端比較少,並且X86的設備基本都兼容了ARM的指令集(會影響功耗),所以再應用程序中,native的程序使用頻率不高或者運算並不復雜的情況下,只包含ARM和ARM-v7a的so,如果不需要使用到neon的指令集,就只包含ARM的編譯的so即可。

3 res

resource的縮寫,這個目錄存放資源文件,包含的多個文件夾由資源的類型和設備硬件的類型兩個維度區分,xhdpi,xxhdpi這些雖然兼容性高了,缺因為更多的資源導致安裝包增長,所以盡量用代碼實現自適應,除非有特別要求的資源文件還是要通過這個適配一下。

4 META-INF

保存應用的簽名信息,簽名信息可以驗證APK文件的完整性。打包時回計算APK中所有文件的完整性,並把這些完整性保存道META-INF文件夾下,應用程序在安裝時首先根據這個文件夾校驗APK的完整性,可以保證apk中的每一個文件都不能被篡改。以此來確保APK應用程序不被惡意修改或者病毒感染,有利於確保應用的完整性和系統的安全性。META-INF目錄下包含的文件有CERT.RSA、CERT.DSA、CERT.SF和MANIFEST.MF,其中CERT.RSA是開發者利用私鑰對APK進行簽名的簽名文件,CERT.SF、MANIFEST.MF記錄了文件中的文件的SHA-1哈希值

5 AndroidManifest.xml

相當於Android應用向系統作自我介紹的配置文件,注冊四大組件,包含了對一些權限的聲明以及使用的SDK版本信息。打包時會編譯這個文件,便於系統識別,編譯之后的格式是AXML,包含了以下內容

1.axml頭:其中的axml頭是固定標示axml文件的,其值固定為0x00090003.
2.axml長度:表示了axml的大小
3.StringDataSegment:XML文件中所有字符串類型保存在此
4.ResourceIdSegment:XML文件中聲明的資源ID保存於此
5.XmlContentSegment:是XML的內容段,按照XML文件中的結構依次排開,保存XML數據內容

6 classes.dex

Java可執行程序,需要先把Java文件編譯成class文件,字節碼都保存在class文件中,Java虛擬機可以通過解釋並執行這些class文件。而Dalvik虛擬機再Java虛擬機進行了優化,執行的是Dalvik字節碼,這些Dalvik字節碼由Java字節碼轉化而來,一般情況下,應用在打包時通過AndroidSDK中的dx工具將Java字節碼轉換成Dalvik字節碼。dx工具可以對多個class文件進行合並重組、優化,達到減小體積,縮短運行時間的目的。

7 proguard.cfg

代碼混淆配置文件。

8 resources.arsc

記錄資源文件和資源ID之間的映射關系,用來根據資源ID尋找資源。Android的開發是分模塊的,res目錄專門用來存放資源文件,在代碼中需要調用資源文件時,只需要調用findViewById()就可以得到資源文件,每當再res文件夾下放一個文件,aapt就會自動生成對應的Id保存再R文件中,調用這個ID就可以,但是只有這個ID還不夠,R文件只是保證編譯程序不報錯,實際上在程序運行期間,系統要根據ID尋找對應的資源路徑,而resources.arsc文件就是用來記錄這些ID和資源文件位置對應關系的文件。
由此可見,APK中的classes.dex、lib
、資源文件是大頭,APK瘦身主要就是優化這三類。

減少安裝包大小的常用方案

代碼混淆

ProGuard是一個開源的Java代碼混淆器,默認集成道SDK中,有以下功能

  • 壓縮:移除無效的類、屬性、方法等。
  • 優化:移除沒用的結構
  • 混淆:把類名、屬性名、方法名替換為一到兩個字母。

常用參數 具體參數參考表

  1. ProGuard配置

    -include{filename} : 從定義的文件中讀取配置參數。
    -basedirectory {directoryname} : 指定基礎目錄為以后對應的檔案名稱。
    -injars{class_path} : 指定要處理的應用程序jar、war和目錄
    -outjars{class_path} : 指定處理完后要輸出的jar、war和目錄的名稱。
    -libraryjars{class_path} : 指定要處理的應用程序jar、war和目錄所需的程序庫文件。
    -dontskipnonpubliclibraryclasses : 指定不忽略非公共的庫類
    -dontskipnonpubliclibraryclassmembers : 指定不忽略包可見的庫類的成員。

  2. 保留選項

    -keep{Modifier}{class_specification} : 保護指定的類文件和類的成員。
    -keepclassmembers{modifier}{class_specification} : 保護指定類的成員
    -keepclasseswithmembers{class_specification} : 保護指定的類和類的成員,但條件是所有指定的類和類的成員要存在。
    -keepnames{class_specification} : 保護指定的類和類的成員名稱(如果不需要混淆)
    -keepclassmembernames{class_specification} : 保護指定的類的成員名稱(不需要混淆)。
    -keepclasseswithmembernames{class_specification} : 保護指定的類和類的成員名稱,如果所有指定的類成員出席(在壓縮步驟之后)。
    -printseeds{filename} : 列出類和類的成員 -keep 選項的清淡,標准輸出到給定的文件。

  3. 壓縮

    -dontshrink:不壓縮輸入的類文件
    -printusage{filename} : 輸出無用文件

  4. 優化

    -dontoptimize: 不優化輸入的類文件
    -assumenosideeffects{class_specification} : 優化時假設指定的方法,沒有任何副作用。
    -allowaccessmodification: 優化時允許訪問並修改有修飾符的類和類的成員。

  5. 混淆

    -dontobfuscate: 不混淆輸入的類文件
    -printmapping{filename} : 輸出映射表
    -applymapping{filename} : 重用映射增加混淆。
    -obfuscationdictionary{filename} : 使用給定文件中的關鍵字作為要混淆方法的名稱。
    -overloadaggressively: 混淆時應用侵入式重載。
    -useuniqueclassmembernames: 確定統一的混淆類的成員名稱來增加混淆。
    -renamesourcefileattribute{string}: 設置源文件中給定的字符串常量。

在studio中使用

按照上邊規則寫完proguard-rules.pro后,再build.gradle中配置minifyEnabled為true

buildTypes {
    debug {
        minifyEnabled false
    }
    release {
        signingConfig signingConfigs.release
        minifyEnabled true
        proguardFiles 'proguard-rules.pro'
    }
}

資源優化

使用Lint刪除冗余資源
Refactor -> Remove Unused Resources

assets 文件夾下的掃描不到,需要手動刪除

資源文件最少化

1、盡量使用一套圖片資源,遇到一些圖片在不同分辨率手機上變化差異過大的情況時,再考慮再相應文件夾下放入這個特定的圖片。
2、使用一套圖,一套布局,多套dimens.xml文件,在使用最小資源的情況下,解決多分辨率適配。
3、使用輕量級的第三方庫。
4、減少項目中的預制圖片,預制圖片改成由服務器下發,盡可能將程序與資源分離。

圖片優化

PNG用來存儲灰度圖像時,灰度圖像的深度最多到16位,存儲彩色圖像時,深度最多到48位。並且可存儲多達16位的透明通道數據。JPG以24位顏色存儲單個位圖。JPG是與平台無關的格式,支持最高級別的壓縮,有損耗且沒有透明通道。

png在aapt打包時會自動壓縮,但是壓縮的有限,如果使用圖片色彩單一,可以降低圖像位數來減少圖片大小,還有就是可以用tinyPng,Zopfli,PNGoo來壓縮

其他優化

避免重復功能的庫:能擴展的庫就盡量不要引入新的庫

使用WebP圖片格式:支持透明度,壓縮比JPG更高,但效果更好,4.2.2以上系統才支持。

插件化:需要臨時下載,建議在用戶使用率不高的功能模塊上使用,或者使用預加載。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM