首先推薦兩個性能優化的最佳指南一個是官方指南--性能--縮減應用體量,另外一個是Android studio的官方指南--配置編譯版本--壓縮您的應用。涵蓋了壓縮應用體積的所有方面,
官網:https://developer.android.google.cn/topic/performance/reduce-apk-size
AS:https://developer.android.google.cn/studio/build/shrink-code
下面針對幾個比較實用的。我們挑選出來我們實戰下。
1、移除未使用的備用資源
Gradle 資源縮減器只會移除未由您的應用代碼引用的資源,這意味着,它不會移除用於不同設備配置的備用資源。如有必要,您可以使用 Android Gradle 插件的 resConfigs
屬性來移除應用不需要的備用資源文件。
例如,大部分應用其實並不需要支持幾十種語言的國際化支持,如果您使用的是包含語言資源的庫(如 AppCompat 或 Google Play 服務),則您的 APK 中將包含這些庫中消息的所有已翻譯語言的字符串,而無論應用的其餘部分是否翻譯爲相同的語言。如果您只想保留應用正式支持的語言,則可以使用 resConfig
屬性來指定這些語言。系統會移除未指定語言的所有資源。
以下代碼段展示瞭如何設置只保留英語和法語的語言資源:
android {
defaultConfig {
...
resConfigs "en", "fr"
}
}
優化前有82個語言285.7KB大小:
優化過後,就只剩英文一種大小爲221.8KB
2、壓縮圖片
- 2.1使用webP格式
WebP 格式提供有損壓縮(如 JPEG)以及透明度(如 PNG),與 JPEG 或 PNG 相比這種格式可以提供更好的壓縮效果。
webp支持透明度,壓縮比比jpg更高但顯示效果卻不輸於jpg,官方評測quality參數等於75均衡最佳。 相對於jpg、png,webp作爲一種新的圖片格式,從Android 4.0+開始原生支持,但是不支持包含透明度,直到Android 4.2.1+才支持顯示含透明度的webp,使用的時候要注意。
可以使用 Android Studio 將現有 BMP、JPG、PNG 或靜態 GIF 圖片轉換爲 WebP 格式。如需瞭解詳情,請參閱使用 Android Studio 創建 WebP 圖片。將所有圖片轉化爲webp,選中圖片文件夾,右鍵選中Convert to WebP即可
完成後可以到減小了100多KB,因爲圖片較少,所以效果可能沒有那麼明顯,但是對原始圖片的壓縮率是很大的,達到了90%左右
原始: 轉化webp:
- 2.2使用tinypng有損壓縮
android打包本身會對png進行無損壓縮,所以使用像tinypng這樣的有損壓縮是有必要的。 重點是Tinypng使用智能有損壓縮技術,以儘量少的失真換來圖片大小的銳減,效果非常好,強烈推薦。 Tinypng的官方網站:http://tinypng.com/
- 2.3使用jpg格式
如果對於非透明的大圖,jpg將會比png的大小有顯著的優勢,雖然不是絕對的,但是通常會減小到一半都不止。 在啓動頁,活動頁等之類的大圖展示區採用jpg將是非常明智的選擇。
- 2.4使用矢量圖形
可以使用矢量圖形創建與分辨率無關的圖標和其他可伸縮媒體。使用這些圖形可以極大地減少 APK 佔用的空間。 矢量圖片在 Android 中以 VectorDrawable
對象的形式表示。藉助 VectorDrawable
對象,100 字節的文件可以生成與屏幕大小相同的清晰圖片。
不過,系統渲染每個 VectorDrawable
對象需要花費大量時間,而較大的圖片則需要更長的時間才能顯示在屏幕上。因此,請考慮僅在顯示小圖片時使用這些矢量圖形。如需詳細瞭解如何使用 VectorDrawable
對象,請參閱使用可繪製資源。
- 2.5縮小大圖
如果經過上述步驟之後,你的工程裏面還有一些大圖,考慮是否有必要維持這樣的大尺寸,是否能適當的縮小。 事實上,由於設計師出圖的原因,我們拿到的很多圖片完全可以適當的縮小而對視覺影響是極小的。
- 2.6覆蓋第三庫裏的大圖
有些第三庫裏引用了一些大圖但是實際上並不會被我們用到,就可以考慮用1x1的透明圖片覆蓋。 你可能會有點不舒服,因爲你的drawable下竟然包含了一些莫名其妙的名稱的1x1圖片
3、so庫優化,只保留armeabi-v7a
在使用一些三方庫的時候,會集成大量的so文件到項目中,這些so文件都對應着不同的CPU架構。Android系統目前支持以下七種不同的CPU架構:ARMv5、ARMv7、x86、MIPS、ARMv8、MIPS64、x86_64,每一個CPU架構對應一個ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。
如果項目中包含第三方SDK或者自己使用了ndk,如果不進行配置會打包全cpu架構的動態庫進入apk。目前市面上絕大部分的CPU架構都是 ARMv7/ARMv8,所以可以在gradle中加入配置,只保留v7,v8。對於真機,只需要保留一個armeabi(armeabi-v7a)就可以了,微信大佬就這麼幹的!這裏不排除有極少數設備會Crash,可能和不同的so有一定的關係,請大家務必測試周全後再發布。
原始gradle配置裏面添加了較多的架構:
ndk {
//設置支持的SO庫架構
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
}
可以看到so的體積佔用了apk體積的70%,我們手機絕大多數都是ARM架構,所以不需要添加這麼多架構的so
我們改爲ARM64:
ndk {
//設置支持的SO庫架構
abiFilters "armeabi-v7a"
}
可以看到包體減少了55%,從原來的22MB減少到9.9MB,效果是非常明顯的
4、使用Lint檢測
在Analyze中:
將檢測出來沒有被引用到的資源文件刪除掉即可,但是需要注意提前備份,以防無法回退回來。lint檢測可以避免刪除掉反射使用的資源,因此是較爲安全的方式。
按照這種方式完成後,apk大小從9.9MB縮小到了9.8MB:
注意:lint
工具不會掃描 assets/
文件夾、通過反射引用的資源或已鏈接至應用的庫文件。此外,它也不會移除資源,只會提醒您它們的存在。
5、開啓混淆
Android代碼混淆,又稱Android混淆,是一種Android APP保護技術,用於保護APP不被破解和逆向分析。
ProGuard的三大作用
- 壓縮:移除未被使用的類、屬性、方法等,並且會在優化動作執行之後再次執行(因爲優化後可能會再次暴露一些未被使用的類和成員。
- 優化:優化字節碼,並刪除未使用的結構。
- 混淆:將類名、屬性名、方法名混淆爲難以讀懂的字母
6、開啓刪除無用資源(與Lint不同)
debug {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
shrinkResources 用來開啓壓縮無用資源,也就是沒有被引用的文件(經過實測是drawable,layout,實際並不是徹底刪除,而是保留文件名,但是沒有內容),但是因爲需要知道是否被引用所以需要配合mififyEnable使用,只有當兩者都爲true的時候纔會起到真正的刪
除無效代碼和無引用資源的目的。與去除無用資源不同的是,比如某個java類沒有用到,被混淆時刪除了,而該類引入了layout資源 ,此時會將這個資源也壓縮掉。
使用混淆最重要是需要配置混淆keep文件,完成後看下效果,包體從9.8MB減少到了7.7MB,效果還是很明顯的:
具體我們來看下他是怎麼縮小包體的:
打開資源文件xml可以看到後面有很多47B大小的佈局文件:
這時我們隨便找一個toast_layout.xml看下源文件和優化後的文件對比:
優化後:
優化前:
再看一個layout_pupup.xml對比:
優化後:
優化前:
可以看到,原來是將沒有用到的文件在編譯時,通過簡單的字符替換掉了,而不是簡單粗暴的將源文件刪除掉,因此大大降低了包體大小
對比lint而言,lint的代碼檢測會直接將無用的資源文件以及ID刪除掉,因此使用lint優化無用資源時需要提前備份好數據,以免無法恢復。
7、自定義要保留的資源
如果您有想要保留或捨棄的特定資源,請在項目中創建一個包含 <resources>
標記的 XML 文件,並在 tools:keep
屬性中指定每個要保留的資源,在 tools:discard
屬性中指定每個要捨棄的資源。這兩個屬性都接受以逗號分隔的資源名稱列表。您可以將星號字符用作通配符。
例如:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
tools:discard="@layout/unused2" />
將該文件保存在項目資源中,例如,保存在 res/raw/keep.xml
。構建系統不會將此文件打包到 APK 中。具體見官網
https://developer.android.google.cn/studio/build/shrink-code
具體使用方式,在raw下新建:keep.xml。裏面填寫不需要混淆的xml文件名稱即可。
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@layout/base_*" />
<!--tools:keep="strict"-->
完成後上面toast_layout.xml以及layout_pupup.xml,就不會被X佔位符替代掉了。
8、在 Android Studio 中使用 Android Size Analyzer
安裝Android Size Analyzer插件,安裝插件後,從菜單欄中依次選擇 Analyze > Analyze App Size,對當前項目運行應用大小分析。分析了項目後,系統會顯示一個工具窗口,其中包含有關如何縮減應用大小的建議
9、避免使用枚舉
單個枚舉會使應用的 classes.dex
文件增加大約 1.0 到 1.4KB 的大小。這些增加的大小會快速累積,產生複雜的系統或共享庫。如果可能,請考慮使用 @IntDef
註釋和代碼縮減移除枚舉並將它們轉換爲整數。此類型轉換可保留枚舉的各種安全優勢。