Android包體積過大,真的會影響績效
highlight: a11y-dark
這篇簡單侃一侃Apk的一個瘦身,對於這個包的體積,不知道大家的公司是怎麼看待的,反正我們公司,上到高層,下到開發,都是非常重視的,每次周例會,各個專案都要彙報,上個版本多大,預計這個版本,增加多少,優化多少,都是彙報的物件,所以啊老鐵們,真的是和績效掛鉤,不是虛的。
Apk瘦身,做為一個Android開發者,這是多多少少都會接觸到的,同樣功能的App,200M和150M,給使用者的第一直覺是不一樣的,如果不是剛需,體積越大,使用者的排斥也就越大,所以啊,鐵子們,你以為瘦身,是簡簡單單的把體積變小,殊不知,直接影響著使用者的真實體驗,在開發中,是很有必要進行實施的,畢竟影響著網路資料流量和下載的等待時間。
如何針對性的做瘦身呢,不妨,我們先看一下,佔用APK記憶體,都有哪些因素,大家可以找到apk包,雙擊,或者如下圖進行選擇一個apk開啟。
開啟後,如下圖:
從上圖中,哪些是比較佔用記憶體的,我們一目瞭然,簡單的分析下:
lib:
存放 aar或so 檔案,針對so檔案可能會有 armeabi、armeabi-v7a、arm64-v8a、x86、x86_64、mips等很多不同cpu架構型別,隨著時代的發展,大部分的應用市場也有了64位的安裝包要求,所以以後的發展,估計只需要支援arm64-v8a這一個即可。
res
這個沒什麼好說的,存放編譯後的資原始檔,如, drawable、layout 等等。
assets
應用程式的資源,應用程式可以使用 AssetManager 來檢索該資源,比如一些靜態資料,圖片資源可以放至此處。
META-INF
該資料夾一般存放於已經簽名的 APK 中,它包含了 APK 中所有檔案的簽名摘要等資訊。
classes.dex
classes 檔案是 Java Class,被 DEX 編譯後可供 Dalvik/ART 虛擬機器所理解的檔案格式
AndroidManifest.xml
Android 的清單檔案,用於描述應用程式的名稱、版本、所需許可權、註冊的四大元件
從以上的檢視apk的記憶體佔用大小,我們就可以有針對性的進行瘦身, 一般而言,無非就是兩個方面,一個是資源入手,另一個就是程式碼入手。
資源入手
圖片的使用
說到資源,就不得不提到圖片,圖片可以說是資源裡佔用記憶體最多的,那麼如何合理的使用圖片呢,首先就是解決多套圖的問題,我們知道,在開發中,針對圖片,有hdpi,xhdpi,xxhdpi,xxxhdpi等不同倍數的資料夾,如果讓UI每個倍數都設計一套圖,雖然在適配上滿足了不同解析度的展示,但無形當中,會增加數倍的體積;相對於當下的市場而言,低解析度的手機越來越少,其實也不用準備很多套圖,特別針對國內市場而言,一般xxhdpi就可以滿足實際的需求了。
除了多套圖的問題,還有就是圖片格式的問題,大家可以發現,相對png,jpg而言,webp格式的圖片在同分辨率下,要小25%以上,不僅可以提高載入速度,而且還節省記憶體,使用webp格式的圖片,何樂而不為。
在實際的開發中,針對圖片除了以上的措施,還有就是點9圖的使用,特別是一些背景圖片,我們就可以讓UI設計一個特別小的圖片,轉換點9後再進行拉伸,這也是節約記憶體的一種方式。
如果專案中有很多體積比較大的圖片,建議放到服務端,改本地載入為遠端載入,如果沒有這個條件,或者產品有規定必須要載入本地的,那麼不妨我們可以走一步程式,那就是圖片壓縮,壓縮後再進行載入;當然了壓縮平臺是有很多的,比如Tinypng。
layout的使用
關於layout,無非就是複用了,比如很多頁面有著共同的佈局,我們就可以單獨的抽出來,使用include,在每個頁面引用即可了,再比如,大部分的頁面都是列表,其實layout檔案也沒必要多建立,使用一個共用的即可。
color,dimens,string,style等
對於這些資原始檔,我們能複用就複用,一般有一套即可。
移除未使用資源
隨著專案的迭代開發,可能有很多的歷史資源,已經用不到了,針對這些檔案,我們就可以進行剔除,當然了,有一些難以發掘的,我們可以在build.gradle檔案裡,開啟shrinkResources
的屬性,這個屬性可以幫助我們移除那些在程式中使用不到的資原始檔。
```kotlin android {
buildTypes {
release {
shrinkResources true
}
}
} ```
程式碼入手
so庫使用
前邊我們針對apk進行分析過,so絕對是佔體積的一個大頭,所以說,針對so,我們需要制定出一套合適的方案,既能減少體積,也能夠平穩執行使用。我們都知道,cpu架構有很多型別,每支援一種,就要有對應的so檔案,像目前我們公司開發的應用,增加一種,可能至少會增加三四十兆的體積,所以,這個是很恐怖的。
但還好,以後主流的大方向是64位, 也就是我們在應用中,只支援一種arm64_v8a即可,但是,主流是主流,目前還是不能支援一種,這個,在實際的開發中已經驗證,如果只支援arm64_v8a,發現在部分手機如紅米手機,就會找不到對應的so檔案,就會發生崩潰,所以,還是要進行多cpu架構型別適配。
那麼怎麼解決這個問題呢?分開打包,也就是64位打64位的,32位打32位的,出不同的包進行上傳,各個應用市場也都是支援的。唯一需要解決的就是,應用內的一個更新問題,這個就需要在多加一層判斷,就是判斷當前手機的cpu架構,然後更新下載對應的apk,這樣就可以解決因so導致的體積增大問題。
當然了,以上的解決方式屬於靜態載入的解決,並沒有根本上解決so佔用記憶體的問題,如果想徹底的解決,那麼就需要動態載入了,也就是本地不放置任何so庫,全從服務端,進行下發,然後動態載入,這個網上也有很多案例,這裡就不細說了。
程式碼複用
這個就無需多言了,抽取父類,抽取工具類等,大家都耳熟能詳了,但還有一種情況,大家需要注意,那就是一個專案存在一種功能即可,比如網路,圖片載入,資料快取等,一個專案如果有多種的話,不能使用起來亂,不好管理,而且還會增加體積,想想看,一個專案,有Glide,Picasso還有Fresco,你的第一想法是什麼?
減少 ENUM 的使用
每減少一個 ENUM 可以減少大約 1.0 到 1.4 KB 的大小。
WebView的使用
針對一些頁面,可以用H5的話,就儘量用H5,H5不僅可以靈活更改,還可以大幅度減少apk的體積,畢竟當對於很多原生開發的頁面,H5只需要一個webview容器。
開啟混淆
在 build.gradle 檔案相應的構建型別中新增 minifyEnabled true。
開啟這些編譯屬性之後,程式在打包的時候就不會把沒有引用到的程式碼編譯進來,以此達到減少安裝包大小的目的。
```kotlin android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' }
}
} ```
支援外掛化
外掛化開發和元件化不同,外掛化開發就是將整個app拆分成很多模組,每個模組都是一個apk(元件化的每個模組是一個lib),最終打包的時候將宿主apk和外掛apk分開打包,外掛apk通過動態下發到宿主apk,進行分解apk大小。
以上呢,簡單的總結了Apk瘦身的一些方式,其實瘦身的工作呢,儘量提前,也就是說,在專案的啟動之時,就應該全方位的考慮,而不是等到日後的亡羊補牢。
- Android自動生成程式碼,視覺化腳手架之基礎資訊配置
- 如何搞一個線上的Shape生成
- 簡單封裝一個易拓展的Dialog
- 整合一個以官網(微信,QQ,微博)為標準的登入分享功能
- Android打造專有Hook第四篇,實戰增量程式碼規範檢查
- Android極簡MVVM,從一個基類庫談起
- Android元件化開發,其實就這麼簡單
- Android打造專有hook,讓不規範的程式碼扼殺在萌芽之中
- Android包體積過大,真的會影響績效
- Android長按圖示展示快捷方式
- Android自動生成Shape資原始檔(下)
- Android自動生成Shape資原始檔,邁出視覺化腳手架第一步!(上)
- Android自動生成程式碼,視覺化腳手架,將大大提高開發效率
- Android自動生成程式碼,視覺化腳手架之環境搭建
- 怎麼去約束程式碼的統一性
- 沒有準備充分,先不要著急投簡歷
- Android如何生成本地或者遠端aar