前段時間領導要求將android apk體積下降下來,所以個人就去了解了下這方面的知識。
當一個apk體積過大時,過大的體積導致編譯的耗時過長跟用戶不愿意去下載,并且版本的更新也會因為體積過大,必須在wifi環境才舍得更新,這樣對于新版本的推廣是得不償失的。所以就有了縮減apk的需求。
apk縮減是一件很有意思的事情,相應的方法也有很多:
1.盡量少的依賴第三方sdk
可以通過抽取第三方關鍵代碼達到快速開發的需求。因為你在引入一個第三方sdk的時候,往往會帶入很多不必要的功能,并且第三方往往還有內部的依賴,需求功能之外的冗余代碼還是蠻多的,所以手動的抽取出關鍵代碼,往往會比較合適,當然,依賴可能造成的其他問題就不在這里一一說明了。
這里做一個小小的示范,如何抽取出關鍵代碼:
抽取代碼目標:PullZoomView :是一種可伸縮的view
//直接依賴:
In your build.gradle:
dependencies {
compile 'com.github.frank-zhu:pullzoomview:1.0.0'
}
我們選擇另一種做法,直接抽取關鍵代碼,現在我們下載代碼, 看他的代碼中都有什么
//我們找到我們想要的控件了,那么現在就只需要抽取所需的代碼就可以了
單純的抽取代碼,發現有非常多的錯誤,這個時候不需要考慮什么,只要把這里報錯所需的代碼全部拷貝過來就可以了。需要什么抽什么
直接抽取類還不夠,我們會發現還有如下的styleable中的代碼要抽取出來:
我們找到res包中需要的代碼拿出來就可以了,如果你沒有attrs.xml文件,just to create:
最后 導入就好了
就這樣,便直接使用這個功能了,有時候你可能還需要復制一些布局文件,稍微注意一下引用的包名就可以了,這個想必難不倒各位的。
可能這種抽取代碼對于一些小項目并沒有什么幫助,但是對于一些大的依賴,比如MPAndroidChart還是挺有用的,我們并不需要那么多的表格展示,只要抽取我們想要的代碼,就可以達到我們的目的了。
2.刪除不需要的代碼跟沒有被引用的圖片
項目的長期迭代,往往會有一些圖片被替代,不被使用,所以可以通過android studio自帶的分析工具lint,進行分析,刪除:
進入Android Studio的菜單中選擇Analyze->Inspecting Code即可
分析完畢后在Inspection選項卡中會有一份詳細的報告,找到Android Lint項目
拉到下面Unused resource這一欄打開,即是未被使用的資源列表,用戶可以參照來手動刪除資源
還有種方法,但是我并沒有去關注這方面會不會帶來潛在的風險,需要大家自己去嘗試:
3.壓縮圖片體積
即使向UI要求盡量減小圖片的大小,但是UI也會因為自己的考量(圖片質量)而不會真正的給出非常小的圖片,那么這個時候需要我們手動的去壓縮圖片,對于這方面,可以通過專門的網站進行批量壓縮,比如 TinyPng
圖片質量肉眼看不出變化,但是大小減小了72% ,就是這么的神奇
4.混淆apk
混淆也是壓縮apk體積的一種,他會將代碼進行替換,這種替換往往會減小代碼占據的體積,一般可以因此降低兩到三兆的體積。混淆需要配置好第三方的proguard-rules.pro 否則會出現功能錯誤
//在app的build.gradle文件下
buildTypes {
debug {
minifyEnabled false
zipAlignEnabled false
shrinkResources false
signingConfig signingConfigs.debug
}
release {
//混淆
minifyEnabled false
//所以盡可能的減少第三方的使用 也是可以降低混淆的難度
//Zipalign優化
zipAlignEnabled true
// 移除無用的resource文件
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
5.優化代碼邏輯,減少Assets文件夾內容
這方面根據項目上面的業務來判斷,比如公司項目由于用了weex,在assets文件夾里面放置了一些vue文件,某些界面直接用vue文件進行展示。由于想盡可能的壓縮apk體積,所以將這一塊的邏輯修改,不再直接加載assets文件夾里面的vue文件,而將所有的vue文件放置到服務器中,根據服務器判斷是否需要下載這方面的文件到用戶的sd卡中,再去加載這方面的文件。這樣,再一次的減小了整個apk的體積。
6.丟棄 跟替換某些占據體積較大的依賴。
可以通過分析網站 ,分析整個apk中的大小分布
7.對于一些市場占有率不高的分辨率,請謹慎支持
即有選擇性的提供xhdpi,xxhdpi的圖片資源。建議優先提供xhdpi的圖片,對于mdpi,ldpi與xxxhdpi根據需要提供有差異的部分即可
8.使用webp格式的圖片資源
webp格式帶來更低的體積,但是有點需要衡量的是,webp圖片的解析需要jpg/png將近10倍的時間消耗,并且需要做好適配的問題。
9.用代碼代替背景圖片
對于一些背景圖片,可以直接用selector.xml文件替代,既不會失真,體積又能進一步的減小。
10. .so包的優化
很多第三方會提供所有的.so包支持,但是我們其實并不需要那么多的架構支持,類似于x86和x86_64(都是模擬器)的so是不需要支持,在這方面也可以減少一部分體積開支:
defaultConfig {
ndk {
// 設置支持的SO庫架構
abiFilters 'armeabi-v7a'// , 'arm64-v8a', 'armeabi-v7a', 'x86_64', 'x86', 'arm64-v8a'
}
}
11.動態加載技術(插件化)
現在大型互聯網移動App很多都采用了動態加載的技術,因為他們的業務需求太大,通過動態加載技術可以將一部分業務模塊獨立出來,以插件的方式分割出去,這樣子主apk的體積就大大減小。當用戶安裝主apk后,靜默的在后臺下載插件apk,當用戶點擊使用到相關的子模塊項目時候,動態的加載插件apk。 動態加載技術無疑從根本上減少了apk的體積,但是引入這個技術是有代價的,增加了項目的維護難度和開發難度。所以該技術適用于大型的移動應用,當你的業務大到不分開模塊難以高效率開發維護的時候,再考慮動態加載技術吧,否則如果小規模應用,還是老老實實考慮傳統的android官方推薦的開發方式。
12.用屬性動畫 代替幀動畫
幀動畫是由一系列的圖片制作而成的,如果需要適配的話,消耗的資源還是很大的。
13.大神專用:使用較低版本的android api ,以便丟棄support.v4包
參考這篇文章
14.移除枚舉
一個枚舉能讓classes.dex文件增加1–1.4K。枚舉的加入會快速增加應用體積。我們可以使用@IntDef注解和Proguard代替枚舉,它能提供和枚舉一樣的類型安全轉換。
15.移除國際化
判斷項目是否真的需要國際化,畢竟不是所有的app都需要去支持外文的。
android {
defaultConfig {
resConfigs "zh"
}
}
16.利用微信資源壓縮打包工具
微信同時利用7z深度壓縮,大大減少了安裝包體積,同時也增加了逼格,提升了反破解難度。
使用說明:微信資源壓縮打包工具使用介紹 技術原理介紹:安裝包立減1M–微信Android資源混淆打包工具
參考:
https://yq.aliyun.com/articles/57284?&utm_source=qq
http://blog.csdn.net/u011335851/article/details/52187739
http://www.lxweimin.com/p/bd90dee57ad0
http://m.blog.csdn.net/article/details?id=50834617
http://blog.csdn.net/tim_yip/article/details/47022875