包結構分析對比
瘦身前
瘦身後
包檔案對比
型別 | 原始大小 | 當前大小 | 縮減型別 |
---|---|---|---|
resource.arsc | 1.9M | 855.9KB | 國際化資原始檔,當前僅保留zh |
res/ | 14.3M | 6.7M | 圖片轉為webp |
assets | 42M | 21.1M | 減少FFmpeg x86平臺編譯檔案 |
lib | 28M | 6.6M | 減少x86平臺下的so檔案 |
1、圖片資源優化
tinypng
- 優點:無相容性問題
- 缺點:壓縮繁雜需上傳至網頁下載,不支援批量壓縮替換
webp
-
優點:有批量新增工具cwebp,可實現批量替換,後期可考慮將webp壓縮新增到自動化打包流程中
-
缺點:有相容性問題,WebP格式是從Android4.0版本開始支援;Android4.0到Android4.2.1之間的版本不支援無失真壓縮和透明格式的WebP圖片的編解碼
最終經過檢視使用者手機型號及版本範圍分佈決定使用webp優化圖片資源,當然如果通過Android studio 一個一個的將圖片轉換為webp顯然是非常耗時且易出錯的,Google官方提供了cwebp工具可以使用指令碼批量壓縮替換,具體語法如下:
execCommand("cwebp", "-q", "80", in, "-o", out)
-q 後面的80表示壓縮比率為原始檔的80%
in 此處傳入原始檔目錄進行替代
-o 後面的 out處傳入原始檔的輸出路徑
圖片批量替換為Webp
``golang``
package main
var fileRealPath string
func init() {
fileRealPath = "/Users/aihuishou/Desktop/opt_rn/android"
//fileRealPath = getCurrentDirectory()
}
func main() {
getFileList(fileRealPath)
}
func getFileList(filep string) {
err := filepath.Walk(filep, func(path string, f os.FileInfo, err error) error {
if f == nil {
return err
}
if f.IsDir() {
return nil
}
png2webp(f.Name(), path)
//deleteWebp(f.Name(),path)
return nil
})
if err == nil {
fmt.Println("轉換完畢")
}
}
// 通過cwebp命令批量替換png圖片
func png2webp(name string, path string) {
var isLauncher = strings.HasPrefix(name, "ic_launcher")
var isPng = strings.HasSuffix(name, ".png")
var isJpg = strings.HasSuffix(name, ".jpg")
var is9png = strings.HasSuffix(name, ".9.png")
// 對png和pjg同時進行處理,排除掉應用圖示及.9圖
if isPng && !isLauncher && !is9png || isJpg {
var out string
if isJpg {
out = strings.TrimSuffix(path, ".jpg") + ".webp"
}
if isPng {
out = strings.TrimSuffix(path, ".png") + ".webp"
}
cmdErr := execCommand("cwebp", "-q", "80", path, "-o", out)
if cmdErr {
println(path, " 替換為 =======> ", out)
del := os.Remove(path)
if del == nil {
println(path, " 刪除成功!")
}
}
}
}
// 刪除當前目錄中的webp檔案
func deleteWebp(name string, path string) {
var isweb = strings.HasSuffix(name, ".webp")
if isweb {
del := os.Remove(path)
if del == nil {
println(path, " 刪除成功!")
}
}
}
// 執行cwebp轉換命令
func execCommand(commandName string, params ...string) bool {
cmd := exec.Command(commandName, params...)
//顯示執行的命令
fmt.Println(cmd.Args)
stdout, err := cmd.StdoutPipe()
if err != nil {
fmt.Println(err)
return false
}
cmd.Start()
reader := bufio.NewReader(stdout)
//實時迴圈讀取輸出流中的一行內容
for {
line, err2 := reader.ReadString('\n')
if err2 != nil || io.EOF == err2 {
break
}
fmt.Println(line)
}
cmd.Wait()
return true
}
複製程式碼
2、主工程瘦身
- 主工程刪除x86平臺支援
- 主工程resConfigs設定為zh,僅支援中文語言包
defaultConfig {
resConfigs "zh"
ndk {
abiFilters "armeabi-v7a"
}
}
複製程式碼
- 主工程gif圖片壓縮
按照主工程GIF圖片實際展示大小進行適當壓縮
3、三方庫瘦身
因為工程中有視訊拼接功能所以新增了FFmpeg-Android庫檔案導致包體積急劇上升,根據專案目前需求可取消對x86平臺的支援
- 下載FFmpeg-Android原始檔講asset中x86下的FFmpeg檔案刪除,設定ABI平臺僅支援armeabi-v7a
- 刪除專案中歷史冗餘程式碼
後記
不同的專案可以根據不同的需求選擇不同的方法進行體積壓縮,下面總結常見的apk壓縮技巧
- 冗餘程式碼和資原始檔清除
可優化內容如下:
程式碼清除(刪除工程中無用程式碼,使用第三方包時,儘量將自己使用的部分原始碼拷貝進專案)
圖片資源清除(在專案對解析度要求不是跟高的前提下可以只支援 xhdpi xxdpi xxxdpi 甚至可以只支援xxdpi xxxdpi兩中解析度 )
- 圖片大小優化
webp
tinypng
- 程式碼混淆
- 資源混淆