精简我们的apk的方法
我們都知道安卓的65K方法坑。
com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536 at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:484) at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:261) at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:473) at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:161) at com.android.dx.merge.DexMerger.merge(DexMerger.java:188) at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:504) at com.android.dx.command.dexer.Main.runMonoDex(Main.java:334) at com.android.dx.command.dexer.Main.run(Main.java:277) at com.android.dx.command.dexer.Main.main(Main.java:245) at com.android.dx.command.Main.main(Main.java:106)最近搞的項目也是輕松超越,哎,現在的項目越來越大,功能越來越多,還沒怎么用,要求一次上齊那么多功能也是挺奇葩的,加班也越來越多,無限的不理解,有點做得很沒意思啊。。
解決方案:
1. 簡單暴力版
刪除沒要so庫,合并一些方法,去掉代碼中沒使用到的函數,去掉沒有使用到的jar包,以及將類中成員由private換成public,減少set/get函數。
雖然這些都是治標不治本的方法,
不過對于在這個邊界65K左右的情況確實很好的一個方法!!
這里有一個包,用來幫助你查看各個package里面的方法數的,
這樣你就可以根據這個做一個參考,替換更小的包等。
2. multidex
谷歌在2014年就提出這個解決方案,這個還是很簡單實惠的!
在我們的build.gradle 文件里面加多multiDexEnabled true,同時加多multidex包!
配置好后,我們需要做的就是修改我們application類。
三種方案:
修改minifest文件,name為MultiDexApplication
<applicationandroid:name="android.support.multidex.MultiDexApplication"android:allowBackup="true"android:icon="@mipmap/icon_app"修改我們的application繼承于MultiDexApplication
public class MyApp extend MultiDexApplication{}修改我們的app的一個函數。
public class MyApplication extends Application { @Overrideprotected void attachBaseContext(Context base) {super.attachBaseContext(base);MultiDex.install(this);}}好了,總共就這樣,我們的apk如果超過65k方法,就會被壓成兩個dex文件。
MultiDex缺陷
但這方案還是有缺陷的,你需要測試下這個壓縮包是否還有效!
- ANR
應用MultiDex后,這個程序在安裝和開啟過程會相對復雜,從而導致ANR問題,如果第二個dex文件比較大的話,在這種情況,你需要使用ProGurad來盡可能的減小dex的大小和移出些沒用的代碼! - 安卓4.0無法啟動
對于運行舊于4.0的系統,因為一個Dalvik linearAlloc的缺陷,會有可能無法啟動。如果你要去支持這部分舊版系統,需要自己測試下,因為在特定累的加載過程都有可能導致bug。 - 內存消耗問題
采用multidex方案的會有更大的內存消耗從而導致程序崩潰,因為有這么一個Dalvik linearAlloc 限制的bug–78035,這個bug雖然在4.0被調整了。
優化建議
在生產的過程會相對的耗費大量的時間的,因為系統要做很多的決定和判斷那些文件放到第一個dex,那些放到第二個DEX里面去。為了縮短build的時間,建議弄兩個flavor,一個是開發測試環境,一個是生產環境的。開發環境設最小SDK為21,因為會使用ART技術來加快生產。對于生產環境就設置實際的
android {productFlavors { dev {minSdkVersion 21}prod { minSdkVersion 14}}...buildTypes {release {runProguard trueproguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'}} }dependencies {compile 'com.android.support:multidex:1.0.1' }測試問題
這帶來的另外一個問題也是測試問題,當我們用instrumentation 來測試時候,需要多額外的配置,具體如下
android {defaultConfig {...testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner"} }如果你的gradle是低于1.1的(話說現在都出到2.0了,還用1.1也太舊了),還需要下面這個:
dependencies {androidTestCompile('com.android.support:multidex-instrumentation:1.0.1') {exclude group: 'com.android.support', module: 'multidex'} }然后你的測試類需要繼承這個,或者在你的onCreate里面改成下面這樣
public void onCreate(Bundle arguments) {MultiDex.install(getTargetContext());super.onCreate(arguments);... }3. 插件化
插件化是一個現對來說很重的一個解決方案,需要修改的地方很多。
具體參考美團的帖子
美團Android DEX自動拆包及動態加載簡介
另外提一點的是,很多大型的為了多團隊的合作,快速的集成,交付等,實用的就是“插件化開發”,
你去看下微信的包,就各種庫,各種插件。
因為需要減輕應用太大時候帶來的內存和cpu占用問題。你看每次打開微信那卡的。簡直。。。。。。
人家已經維持優化了很多還是這樣,可見。安卓手機實在不給力啊。。。。
關于動態加載技術,網上有很多文章,剛興趣的可以自己看下。
參考資料
谷歌的官方解釋:Building Apps with Over 65K Methods
總結
以上是生活随笔為你收集整理的精简我们的apk的方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 启用计算机的无线同屏,完美:将计算机转换
- 下一篇: swf web 播放