2M-APK瘦身實測可行又便捷的方法 (應用上架 陣前磨槍)
新專案上線,新應用原始apk大小在6.9M左右,然後公司和第三方運營公司合作,加入其提供的第三方SDK,瞬間apk體積增大3M;接著為了應用上線後的安全性,對應用進行了加固處理,套了一層殼之後,應用又增大了1.7M,最後上線之前包的體積已經超過10M,計算器這一工具類的應用包體積超過10M就沒有很強的競爭力了,所以減小包體積的工作勢在必行。
下面是博主實際運用到的一些方法,沒有囊括所有的方案,但都是有效的方案:
1).刪除專案中無用的資源
Menu - >Refactor ->Remove unused resources
AS搜尋一段時間之後會在下方彈出提示框,點選“do refactor”就可以將專案中無用的資原始檔全部清除,包括圖片,各種xml檔案。注意:機器沒有智慧到那種程度,所以直接刪除可能會導致一些錯誤,使得之後編譯不通過,所以建議在直接刪除之前使用快捷鍵“alt + F7
2).清除專案中無用的import包
Menu - >Code ->Optimize Imports | 專案根目錄下右鍵->Optimize Imports
以上是直接去掉整個專案中的import包,若在某個檔案中去除可使用快捷鍵“ctrl+alt+o”。
也可在設定裡直接設定為自動清除無用的import包(可自動匯入包,當然也可以設定為自動刪除包)。
Setting - >Editor - >General - >Auto Import - >Optimize imports on the fly
以上兩步操作完之後,整個應用包減小0.7M。
3)包體分析 (Android Studio 2.2以上)- 從內到外瞭解
Menu - >build->Analyze APK
①lib/ -> 存放so檔案,可能會有armeabi、armeabi-v7a、arm64-v8a、x86、x86_64、mips,大多數情況下只需要支援armabi與x86的架構即可,如果非必需,可以考慮拿掉x86的部分;
②res/ -> 存放編譯後的資原始檔,例如:drawable、layout等等;
③assets/ -> 應用程式的資源,應用程式可以使用AssetManager來檢索該資源;
④META-INF/ -> 該資料夾一般存放於已經簽名的APK中,它包含了APK中所有檔案的簽名摘要等資訊;
⑤classes(n).dex -> classes檔案是Java Class,被DEX編譯後可供Dalvik/ART虛擬機器所理解的檔案格式;
可以看到佔用空間的主要是程式碼、圖片、資源和lib和assert檔案,主要方向精簡程式碼、壓縮圖片、去除無用的庫、減少asserts裡面檔案。
有了方向之後,那麼開始進行瘦身:
a.asserts資料夾內去除佔用空間較大的字型檔案,既使得包的體積減小(一個字型檔案100-200k),又使得應用字型變得更為統一;
b.開啟資源壓縮
android {
...
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
minifyEnabled 設為true時會自動對程式碼進行清理,打包時去掉無用的程式碼部分,所以編譯速度會受到影響;
shrinkResources設為true時打包會自動根據minifyEnabled 為true時去掉的程式碼部分再次去掉該程式碼部分相關的資原始檔部分,注意二者是配合使用的。
注:build.gradle中配置二者時只是在打包檔案中去掉了無用的部分,專案中還是實際存在的。
c.語言資源優化,原專案中產品經理要求配置三種語言:中文 英文 法語,最終上線前為包體積做考慮,只啟用英語一門語言配置(應用是釋出在谷歌應用市場)。
android {
...
defaultConfig {
...
resConfigs "en"
}
...
}
如果不做任何配置的話,最終APK包中會包含專案中所有已翻譯語言字串,無論應用的其餘部分是否翻譯為同一語言,可以通過resConfig來配置使用哪些語言,從而讓構建工具移除指定語言之外的所有資源。
d.圖片壓縮,原本專案中使用的圖片都是32*32的png圖片,後來為清晰度的考慮將圖片同一替換成72*72的png,結果每張圖片都有200k左右,這裡推薦使用tinypng網站進行圖片無失真壓縮,下面這張圖從190k壓到1.6k,肉眼基本看不出任何區別;
這兩張圖示 一張被壓縮了97%,你相信嗎?
e.優化classes.dex,這裡無定式方法,主要是提供一些思路 —— 時刻保持良好的程式設計習慣和對包體積敏銳的嗅覺,去除重複或者不用的程式碼,慎用第三方庫,選用體積小的第三方SDK等等。
以上四步操作完之後,整個應用包減小0.5M。
4)APK瘦身放大招 - AndResGuard的使用
①概念:AndResGuard是一個縮小APK大小的工具,它的原理類似Java Proguard,但是隻針對資源。它會將原本冗長的資源路徑變短,例如將res/drawable/wechat變為r/d/a(是的,如同混淆一樣的abc,通過進一步混淆res資源夾來減小包體積)。
②配置
專案根目錄下build.gradle中,新增外掛的依賴:
dependencies {
classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.10'
}
專案根目錄中build.gradle中,再新增白名單配置:
apply plugin: 'AndResGuard'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.10'
}
}
andResGuard {
mappingFile = null
use7zip = true
useSign = true
keepRoot = false
whiteList = [
// your icon
"R.drawable.icon",
// for fabric
"R.string.com.crashlytics.*",
// for umeng update
"R.string.tb_*",
"R.layout.tb_*",
"R.drawable.tb_*",
"R.drawable.u1*",
"R.drawable.u2*",
"R.color.tb_*",
// umeng share for sina
"R.drawable.sina*",
// for google-services.json
"R.string.google_app_id",
"R.string.gcm_defaultSenderId",
"R.string.default_web_client_id",
"R.string.ga_trackingId",
"R.string.firebase_database_url",
"R.string.google_api_key",
"R.string.google_crash_reporting_api_key",
//友盟
"R.string.umeng*",
"R.string.UM*",
"R.layout.umeng*",
"R.drawable.umeng*",
"R.id.umeng*",
"R.anim.umeng*",
"R.color.umeng*",
"R.style.*UM*",
"R.style.umeng*",
]
compressFilePattern = [
"*.png",
"*.jpg",
"*.jpeg",
"*.gif",
"resources.arsc"
]
sevenzip {
artifact = 'com.tencent.mm:SevenZip:1.2.10'
}
}
其中whiteList(白名單)中指定不需要進行混淆的資源路徑規則,主要是一些第三方SDK,因為有些SDK的程式碼中引用到對應的資原始檔,如果對其進行混淆,會導致找不到對應資原始檔,出現crash,所以不能對其資原始檔進行混淆。由於公司的專案中使用到了友盟和融雲,所以將這兩個SDK加入白名單,更多的白名單可以檢視:
③打包
不再使用AS自帶打包方法,而是使用gradle的打包方法,AS右側點選Gradle開啟Gradle任務列表:
打release包,只需要雙擊resguardRelease,開始打包(時間較長),執行完畢後,可以在app目錄下的/build/output/apk/release/AndResGuard_{apk_name}/ 資料夾中找到混淆後的Apk,其中app-release_aligned_signed.apk為進行混淆並簽名過的apk,雙擊檢視該apk,再次開啟res資料夾就會發現所有的檔名都已經再次混淆了。
操作完這一步之後,整個apk減小了0.8M
通過以上的一些apk瘦身常用方法,最終包減小了2M左右,值得一提的是,如果使用一種瘦身方法沒有明顯的效果時,就可以放棄再尋找其他方法,不要死磕(別問我為什麼這樣說)。
PS:臨時抱佛腳,應用上架前被附加了那麼多東西,然後才開始做apk瘦身,博主多少有些無奈。不過學到了很多!以後不會被弄的手忙腳亂的了。