APK瘦身方向:
-
代碼方面
除必要的封裝外,還可以通過混淆壓縮release { minifyEnabled true // 是否混淆 //去除無效的文件,但目前還不支持移除app和libray中的values目錄下的資源文件(strings,dimensions,styles,colors),這些我//們可以使用Splits解決 shrinkResources true // 混淆的配置文件 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } lib
輕量級lib是首選;so本地庫
主流的架構都是arm的;-
資源文件(圖片,音頻,字體等)
a. 通過Lint工具掃描代碼中沒有使用到的靜態(tài)資源,但不包括assets中的文件,方法:在As的 Analyze –>Inspect Code,并合理刪除無用代碼;b. 圖片處理及優(yōu)化方面
- 必要時可采用圖片旋轉方式代替添加新的圖片:
<rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/blue_btn_icon" android:fromDegrees="180" android:pivotX="50%" android:pivotY="50%" android:toDegrees="180" /> - 在某些時候jpeg可以減少圖片的體積(無alpha屬性);
- 9.png的圖片,特點是可拉伸;
- 在不降低圖片效果、保證APK顯示效果的前提下縮小圖片-如使用tinypng優(yōu)化大部分圖片資源(缺點:對有過渡效果(帶alpha值)的圖片不能使用,會造成圖片失真,這種圖片可以將png圖片轉換為webP格式(軟件:iSparta));
- 用svg替換原來圖片能立刻將圖片減少,而且不用考慮分辨率適配的問題。但在As中需要vectorDrawable配合。
d. 清除你的無用的代碼以及資源
查詢到的都是對當前項目無貢獻的資源: Analyze –>Run Inspection by name –> unused resources
-
分析得到沒有用的類及方法: Analyze –>Run Inspection by name –> unused declaration
注意:上述兩個方法,查詢到的文件中也包括了一些需要保留的資源,手動刪除前還是需要分析下的(資源使用查詢:alt+F7,刪除文件:alt+Del)
-
指定資源配置
android { ...... productFlavors { cs { resConfigs "zh","xxhdpi" //指定資源配置 ext.dexOptions = false //調試構建停用 Crashlytics ext.alwaysUpdateBuildId = false //阻止 Crashlytics 不斷更新其構建 ID } } }注意:
無論時尺寸適配還是語言適配,都需要有values這個文件夾,并且values-zh或values-400x320中的所有文件,在values中也"必須也要有",否則會報錯
e. 混淆配置參考:http://www.itdecent.cn/writer#/notebooks/9538856/notes/28822848
- 必要時可采用圖片旋轉方式代替添加新的圖片:
apk打包
-
配置產品風味實現多個變體:
變體可以理解為apk變體,多少種變體就是多少種apk類型;公式:
變體數 = 被標記為不同種維度的產品風味個數的乘積 * 構建類型個數 - 過濾變體構建類型個數
(如下邊例子的 變體數 = 232 - 12 = 10)flavorDimensions "mode","suffix" //產品風味組(也稱風味維度,其中有兩種維度,優(yōu)先級前高后低,不同維度的產品風味會自由組合) productFlavors { //產品風味配置標志 cancell{ //產品風味名 dimension "suffix" versionNameSuffix "-csss" } dess{ //產品風味名 dimension "suffix" versionNameSuffix "-devss" } cs { //產品風味名 dimension "mode" resConfigs "zh","en","xxhdpi" ext.dexOptions = false //調試構建停用 Crashlytics ext.alwaysUpdateBuildId = false //阻止 Crashlytics 不斷更新其構建 ID buildConfigField 'String', 'API_URL', "\"https://cs.XXX\"" buildConfigField 'String', 'WETCHAT_ID', "\"XXX\"" buildConfigField 'String', 'PAY_URL', "\"https://XXX\"" manifestPlaceholders = [JPUSH_APPKEY: "XXX", JPUSH_PKGNAME: "com.XXX.app", JPUSH_CHANNEL: "developer-default",UMENG_CHANNEL_VALUE: "cs"] } dev { //產品風味名 dimension "mode" buildConfigField 'String', 'API_URL', "\"https://cs.XXX\"" buildConfigField 'String', 'WETCHAT_ID', "\"XXX\"" buildConfigField 'String', 'PAY_URL', "\"https://XXX\"" manifestPlaceholders = [JPUSH_APPKEY: "XXX", JPUSH_PKGNAME: "com.XXX.app", JPUSH_CHANNEL: "developer-default",UMENG_CHANNEL_VALUE: "dev"] } prod { //產品風味名 dimension "mode" buildConfigField 'String', 'API_URL', "\"https://cs.XXX\"" buildConfigField 'String', 'WETCHAT_ID', "\"XXX\"" buildConfigField 'String', 'PAY_URL', "\"https://XXX\"" manifestPlaceholders = [JPUSH_APPKEY: "XXX", JPUSH_PKGNAME: "com.XXX.app", JPUSH_CHANNEL: "developer-default",UMENG_CHANNEL_VALUE: "prod"] } } //變體過濾器,可以過濾掉種變體,配置后在Build > Select Build Variant(或工具窗口欄中的 Build Variants)中,這些構建變體將不會再顯示在下拉菜單中。 variantFilter { variant -> def names = variant.flavors*.name if (names.contains("cancell") && names.contains("cs")) { setIgnore(true) } } buildTypes { //構建類型 debug { //構建類型名 signingConfig signingConfigs.debug minifyEnabled false //混淆 zipAlignEnabled true //zipalign優(yōu)化 shrinkResources false //移除無用resources } release { //構建類型名 signingConfig signingConfigs.release zipAlignEnabled true //zipalign優(yōu)化 minifyEnabled false shrinkResources false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } -
Splits構建不同density和ABI 的APK:
android { ... splits { density { enable true exclude "ldpi", "tvdpi", "xxxhdpi" //不能與reset()一起使用 compatibleScreens 'small', 'normal', 'large', 'xlarge' } } android { ... splits { abi { enable true reset() include 'x86', 'armeabi-v7a', 'mips' //必須與reset()一起使用 universalApk true } } } 參數解析: enable: 啟用屏幕密度拆分機制 exclude: 默認情況下所有屏幕密度都包括在內,你可以移除一些密度。 include: 表示要包括哪些屏幕密度 reset(): 重置屏幕密度列表為只包含一個空字符串 (這能夠實現,在與include一起使用時可以表示使用哪一個屏幕密度,而不是要忽略哪一些屏幕密度) compatibleScreens:表示兼容屏幕的列表。這將會注入到manifest中匹配的 節(jié)點。這個設置是可選的。 universalApk:指示是否打包一個通用版本(包含所有的ABI)。默認值為 false。 -
其他
查看生產的apk各個資源占用情況:
a. 先要用As生產一個apk;
b. build-Analyze Apk(或者在生產apk時會有analyze提示);當apk安裝不上問題解決:
如錯誤信息:It is possible that this issue is resolved by uninstalling an existing version of the apk if it is present, and then re-installing.時,在手機上有沒有找到此應用的應用圖標,這也有可能是該應用的某個模塊在手機上隱式安裝了,我們可以先查看工程中都有那些模塊(android庫模塊),記下這些模塊名稱,再到手機的程序管理中去找,若是有則卸載即可;