Android效能優化之apk瘦身技巧
隨著專案迭代,新功能的增加。回導致apk越大。那麼在下載安裝過程中。使用者耗費的流量越多。 安裝等待的時間也會越長。這就意味著下載轉化率會越低。那麼如何apk瘦身呢?
理解APK結構
在討論怎麼減小Apk體積之前,理解一個應用的APK結構是非常有幫助的。一個apk檔案就是由一個zip壓縮包組成,這個zip包含了所有組成你應用的檔案。這些檔案包含了java的位元組碼檔案,資原始檔和一個包含了編譯後資源的檔案。 一個apk包含了如下的目錄:
- META-INF/: 包含了CERT.SF和CERT.RSA簽名檔案,以及MANIFEST.MFmanifest 檔案.
- assets/:包含了應用的assets,應用可以通過 AssetManager物件來獲取這些資源.
- res/:包含了沒有被編譯成resources.arsc的所有資源.
- lib/:包含了用於軟體處理的編譯後的程式碼,這個目錄還包含了針對不同平臺型別的子目錄 armeabi, armeabi-v7a, arm64-v8a, x86, x86_64和mips.
一個APK還包含了如下的檔案,但是其中只有AndroidManifest.xml是必須的。
- esources.arsc:包含了編譯後的資源。這個檔案包含了res/values/資料夾下面的所有XML檔案內容,打包工具抽取了XML檔案內容,並把它編譯成二進位制檔案格式,並且進行壓縮。該內容包含了language strings(語言相關的字串)和styles,並且包括沒有直接放在resources.arsc檔案中的內容路徑,比如layout檔案以及圖片檔案.
- classes.dex:包含了class檔案編譯成的dex檔案,這是可以被Dalvik/ART虛擬機器識別的檔案格式。
- AndroidManifest.xml:包含了Android核心manifest檔案。這個檔案羅列了應用的名字,版本,訪問許可權和引用的library庫。該檔案採用Android的二進位制XML格式。
包體分析
可以看到佔用空間的主要是程式碼、圖片、資源和lib和assert檔案,主要方向精簡程式碼、壓縮圖片、去除無用的庫、減少asserts裡面檔案。
使用Progruard
在proguard中,是否保留符號表對APP的大小是有顯著的影響的,可酌情不保留,但是建議儘量保留用於除錯
引數:
-include {filename} 從給定的檔案中讀取配置引數
-basedirectory {directoryname} 指定基礎目錄為以後相對的檔案名稱
-injars {class_path} 指定要處理的應用程式jar,war,ear和目錄
-outjars {class_path} 指定處理完後要輸出的jar,war,ear和目錄的名稱
-libraryjars {classpath} 指定要處理的應用程式jar,war,ear和目錄所需要的程式庫檔案
-dontskipnonpubliclibraryclasses 指定不去忽略非公共的庫類。
-dontskipnonpubliclibraryclassmembers 指定不去忽略包可見的庫類的成員。
保留選項 :
keep {Modifier} {class_specification} 保護指定的類檔案和類的成員
-keepclassmembers {modifier} {class_specification} 保護指定類的成員,如果此類受到保護他們會保護的更好
-keepclasseswithmembers {class_specification} 保護指定的類和類的成員,但條件是所有指定的類和類成員是要存在。
-keepnames {class_specification} 保護指定的類和類的成員的名稱(如果他們不會壓縮步驟中刪除)
-keepclassmembernames {class_specification} 保護指定的類的成員的名稱(如果他們不會壓縮步驟中刪除)
-keepclasseswithmembernames {class_specification} 保護指定的類和類的成員的名稱,如果所有指定的類成員出席(在壓縮步驟之後)
-printseeds {filename} 列出類和類的成員-keep選項的清單,標準輸出到給定的檔案
壓縮 :
-dontshrink 不壓縮輸入的類檔案
-printusage {filename}
-whyareyoukeeping {class_specification}
優化 :
-dontoptimize 不優化輸入的類檔案
-assumenosideeffects {class_specification} 優化時假設指定的方法,沒有任何副作用
-allowaccessmodification 優化時允許訪問並修改有修飾符的類和類的成員
混淆 :
dontobfuscate 不混淆輸入的類檔案
-printmapping {filename}
-applymapping {filename} 重用對映增加混淆
-obfuscationdictionary {filename} 使用給定檔案中的關鍵字作為要混淆方法的名稱
-overloadaggressively 混淆時應用侵入式過載
-useuniqueclassmembernames 確定統一的混淆類的成員名稱來增加混淆
-flattenpackagehierarchy {package_name} 重新包裝所有重新命名的包並放在給定的單一包中
-repackageclass {package_name} 重新包裝所有重新命名的類檔案中放在給定的單一包中
-dontusemixedcaseclassnames 混淆時不會產生形形色色的類名
-keepattributes {attribute_name,...} 保護給定的可選屬性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.
-renamesourcefileattribute {string} 設定原始檔中給定的字串常量
開啟shrinkResources去除無用資源
在gradle使用shrinkResources去除無用資源,效果非常好。
android {
buildTypes {
release {
shrinkResources true
}
}
}
刪除無用的語言資源
大部分應用其實並不需要支援幾十種語言的國際化支援。還好強大的gradle支援語言的配置,比如國內應用只支援中文:
android {
defaultConfig {
resConfigs "zh"
}
}
使用Android Lint
進入Android Studio的選單中選擇Analyze->Inspecting Code即可。找到Unused resource這一欄開啟,即是未被使用的資源列表,使用者可以參照來手動刪除資源
使用tinypng有失真壓縮PNG和JPEG檔案,
TinyPNG工具只支援上傳PNG圖片到官網上壓縮,然後下載儲存,在保持alpha通道的情況下對PNG的壓縮可以達到1/3之內,而且用肉眼基本上分辨不出壓縮的損失. Tinypng的官方網站:http://tinypng.com/
使用jpg格式
如果對於非透明的大圖,jpg將會比png的大小有顯著的優勢,雖然不是絕對的,但是通常會減小到一半都不止。 在啟動頁,活動頁等之類的大圖展示區採用jpg將是非常明智的選擇。
使用webp格式
webp支援透明度,壓縮比比jpg更高。但是顯示效果卻不輸於jpg .官方評測quality引數等75均衡最佳
刪除armable-v7和X86包下的so 。
基本上armable的so也是相容armable-V7。x86機型是需要X86的。建議實際工作的配置只考慮armable、armable-x86下的so
向量圖、使用shape背景替換圖片、避免重複庫、清理第三方庫和冗餘程式碼、外掛化、