APK瘦身是長久以來的難題,我們需要通過一些工具和技巧才能讓它瘦下去,下面我來分享一下我在apk瘦身方面的經驗。
一、apk中有哪些東西
1.代碼
2.lib
3.so本地庫
4.資源文件(圖片,音頻,字體等)
二、針對性解決問題
1.代碼
我們代碼的優化可以通過混淆來刪除沒有用到的代碼:
buildTypes {
debug {
}
release {
minifyEnabled true // 是否混淆
shrinkResources true // 是否去除無效的資源文件
// 混淆的配置文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
詳細請參考:http://www.cnblogs.com/tianzhijiexian/p/4457763.html
2.lib
盡量不用太復雜的lib,輕量級lib是首選。如果你的應用沒用到兼容庫,可以考慮去掉support包。
3.so本地庫
一個硬件設備對應一個架構(mips、arm或者x86),只保留與設備架構相關的庫文件夾(主流的架構都是arm的,mips屬於小眾,默認也是支持arm的so的,但x86的不支持)
4.資源文件
通過Lint工具掃描代碼中沒有使用到的靜態資源。請參考:
在Android Stuido中使用Lint
需要注意的是:Lint 會分析資源文件(比如 /res
文件夾下面的文件) ,但是會跳過 assets 文件 ( /assets
文件夾下面的文件)。事實上assets 文件是可以通過它們的文件名直接訪問的,而不需要通過Java引用或者XML引用。因此,Lint 也不能判定某個 asset 文件在項目中是否有用。這全取決於開發者對這個文件夾的維護了。如果你沒有使用某個asset 文件,那么你就可以直接清除這個文件。
5.用一張圖片來實現button.selector的多種狀態
解決思路是:用通用的遮罩來建設重復的圖片,詳情參考:
用一張圖片實現按鈕按下和普通效果的樣式
如果是5.0以上的版本:
通常按鈕的正反旋圖片我們都是通過提供一張按鈕正常圖片和一張按鈕反選圖片,然后通過selector實現,兩張圖片除了alpha值不一樣外其它的內容都是重復的,在Android 5.0及以上的版本可以通過tintcolor實現只提供一張按鈕的圖片,在程序中實現按鈕反選效果,前提是圖片的內容一樣,只是正反選按鈕的顏色不一樣。
6.復用現有的圖片,多用shape和layer-list
shape和layer-list一個可以畫出很多常規的圖像,另一個可以將現有的圖像進行組合。通過這兩個東西可以讓我們最大限度的復用現有的圖片。盡可能的重用已有的圖片資源。
對於下面的圖片:
我們可以只要求設計師提供鉛筆的icon,后面用shape畫一下背景就好,而不是要全部的圖片。
對於對稱的圖片,只需要提供一張,另外一張圖片可以通過代碼旋轉的方式實現,需要用到的就是animation的一個小技巧。下面分享一下使用的步驟:
我建立一個rotate_drawable.xml文件:
<?xml version="1.0" encoding="utf-8"?> <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" />
然后,在button設置background:
<ImageButton android:layout_width="100dp" android:layout_height="100dp" android:background="@drawable/rotate_drawable"/>
7.優化現有的圖片
- jpeg還是png,根據需要做選擇,在某些時候jpeg可以減少圖片的體積。
- 對於9.png的圖片,可拉伸區域盡量切小,另外可以通過使用9.png拉伸達到大圖效果的時候盡量不要使用整張大圖。
- 有選擇性的提供hdpi,xhdpi,xxhdpi的圖片資源。建議優先提供xhdpi的圖片,對於mdpi,ldpi與xxxhdpi根據需要提供有差異的部分即可。
8.壓縮現有的圖片
圖片資源的優化原則是:在不降低圖片效果、保證APK顯示效果的前提下縮小圖片文件的大小。
8.1 使用tinypng優化大部分圖片資源:
使用tinypng優化Android的資源圖片
tinypng的缺點是在壓縮某些帶有過渡效果(帶alpha值)的圖片時,圖片會失真,這種圖片可以將png圖片轉換為下面介紹的webP格式,可以在保證圖片質量的前提下大幅縮小圖片的大小。
8.2 把現有圖片轉換為webP
其他圖片和webP之間相互轉換
10.使用VectorDrawable和SVG圖片來替換原有圖片
用svg替換原來圖片可是一個大殺,能立刻將圖片減少,而且不用考慮分辨率適配的問題。那么將svg圖片導入工程呢?答:需要配合vectorDrawable。
在android5.0(API Level 21)中,我們可以使用矢量圖:vector drawable,vector drawable的特點是它不會因為圖像的縮放而失真。在安卓開發中也就意味着你不需要為不同分辨率的設備定義不同大小的圖片資源,只需一個vector drawable就夠了。
<!-- res/drawable/vectordrawable.xml --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="64dp" android:width="64dp" android:viewportHeight="600" android:viewportWidth="600"> <group android:name="rotationGroup" android:pivotX="300.0" android:pivotY="300.0" android:rotation="45.0" > <path android:name="v" android:fillColor="#000000" android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /> </group> </vector>
如果想深入了解請參考:
http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0123/2346.html
http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0201/2396.html
http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0301/2514.html
http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0301/2515.html
http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0306/2553.html
在低版本中可以使用開源的第三方庫來實現:
https://github.com/wnafee/vector-compat
https://github.com/telly/MrVector
9.資源文件最少化配置
Android 開發經常會依賴各種外部開源代碼庫,比如Android Support Library, Google Play Services, Facebook SDK 等等。但是這些庫里面並不是所有的資源文件你都會用到。比如, Google Play Services 里面會有一些為其他語種提供翻譯,而你的app又不需要這個語種的翻譯,而且這個庫里面還包含了我的app中不支持的 mdpi 資源文件。
還好從Android Gradle Plugin 0.7 開始,你可以配置你的app的build系統。這主要是通過配置 resConfig
和 resConfigs
以及默認的配置選項。下面的 DSL (Domain Specific Language)就會阻止 aapt(Android Asset Packaging Tool)打包app中不需要的資源文件。
defaultConfig { // ... resConfigs "en", "de", "fr", "it" resConfigs "nodpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi" }
你也可以用這個方式:
Density Splits
android { ... splits { density { enable true exclude "ldpi", "tvdpi", "xxxhdpi" compatibleScreens 'small', 'normal', 'large', 'xlarge' } }
ABIs Splits
android { ... splits { abi { enable true reset() include 'x86', 'armeabi-v7a', 'mips' universalApk true } } }
詳細請參考:http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
參考自:
http://zmywly8866.github.io/2015/04/06/decrease-apk-size.html
http://hukai.me/android-tips-for-reduce-apk-size/
http://hao.jser.com/archive/1634/
http://stackoverflow.com/questions/20599840/gradle-builds-for-every-resource-folder