編輯:Android資訊
近日,Android Developers在Google+上宣布了新的Multidex支持庫,為方法總數超過65K的Android應用提供了官方支持。
如果你是一名幸運的Android應用開發者,正在開發一個前景廣闊的應用,不斷地加入新功能、添加新的類庫,那麼終有一天,你會不幸遇到這個錯誤:
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536
這個錯誤是Android應用的方法總數限制造成的。Android平台的Java虛擬機Dalvik在執行DEX格式的Java應用程序時,使用原生類型short來索引DEX文件中的方法。這意味著單個DEX文件可被引用的方法總數被限制為65536。通常APK包含一個classes.dex文件,因此Android應用的方法總數不能超過這個數量,這包括Android框架、類庫和你自己開發的代碼。
這個問題可以通過將一個DEX文件分拆成多個DEX文件解決。Facebook介紹了為Android應用開發的Dalvik補丁;Android Developers博客介紹了通過自定義類加載過程的方法來解決此問題。但這些方法有些復雜而且並不優雅。
隨著新的MultiDex支持庫發布,Google正式為解決此問題提供官方支持。構建超過65K方法數的應用介紹了如何使用Gradle構建多DEX應用。
首先使用Android SDK Manager升級到最新的Android SDK Build Tools和Android Support Library R21。然後進行以下兩步操作:
1.修改Gradle配置文件,啟用MultiDex並包含MultiDex支持:
android { compileSdkVersion 21 buildToolsVersion "21.1.0" defaultConfig { ... minSdkVersion 14 targetSdkVersion 21 ... // Enabling multidex support. multiDexEnabled true } ... } dependencies { compile 'com.android.support:multidex:1.0.0' }
2.讓應用支持多DEX文件。在MultiDexApplication JavaDoc中描述了三種可選方法:
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); }
經過以上步驟,你的應用已經可以實現多個DEX文件了。當應用構建時,構建工具會分析哪些類必須放在第一個DEX文件,哪些類可以放在附加的DEX文件中。當它創建了第一個DEX文件(classes.dex)後,如果有必要會繼續創建附加的DEX文件,如classes2.dex, classes3.dex。Multidex的支持類庫將被包含在應用的第一個DEX文件中,幫助實現對其它DEX文件的訪問。
文中還介紹了在開發多DEX應用時,通過設置productFlavors提高開發效率以及多DEX應用的測試方法。
Android 5.0和更高版本使用名為ART的運行時,它原生支持從APK文件加載多個DEX文件。在應用安裝時,它會執行預編譯,掃描classes(..N).dex文件然後將其編譯成單個.oat文件用於執行。了解更多關於ART的信息。
雖然Google解決了應用總方法數限制的問題,但並不意味著開發者可以任意擴大項目規模。Multidex仍有一些限制:
避免應用過大、方法過多仍然是Android開發者要注意的問題。Mihai Parparita的開源項目dex-method-counts可以用於統計APK中每個包的方法數量。
通常開發者自己的代碼很難達到這樣的方法數量限制,但隨著第三方類庫的加入,方法數就會迅速膨脹。因此選擇合適的類庫對Android開發者來說尤為重要。
開發者應該避免使用Google Guava這樣的類庫,它包含了13000多個方法。盡量使用專為移動應用設計的Lite/Android版本類庫,或者使用小類庫替換大類庫,例如用Google-gson替換Jackson JSON。而對於Google Protocol Buffers這樣的數據交換格式,其標准實現會自動生成大量的方法。采用Square Wire的實現則可以很好地解決此問題。
回顧上一篇文章 《Android應用架構概述》 ,我們知道,Android App 本質上抽象成兩個層次:視圖和數據。為了App在發展過程中快速的適應變化,方便維
我們知道大多數的 Android 應用程序都是通過和服務器進行交互來獲取數據的。如果使用 HTTP 協議來發送和接收網絡數據,就免不了使用 HttpURLConn
roid 6.0的源碼剖析, 本文深度剖析Binder IPC過程, 這絕對是一篇匠心巨作,從Java framework到Native,再到Linux Kern
關於Android性能優化中一個常見的建議是不要在你的代碼中使用Enums,就連 Android官網 上都強烈建議不要使用。 Why Android中當你的Ap