當前位置:編程學習大全網 - 源碼下載 - multidex支持庫 eclipse怎麽配置

multidex支持庫 eclipse怎麽配置

[java] view plaincopy

UNEXPECTED TOP-LEVEL EXCEPTION:

java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536

at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:501)

at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:282)

at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:490)

at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:167)

at com.android.dx.merge.DexMerger.merge(DexMerger.java:188)

at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:439)

at com.android.dx.command.dexer.Main.runMonoDex(Main.java:287)

at com.android.dx.command.dexer.Main.run(Main.java:230)

at com.android.dx.command.dexer.Main.main(Main.java:199)

at com.android.dx.command.Main.main(Main.java:103)

沒錯,妳的應用中的Dex 文件方法數超過了最大值65536的上限,簡單來說,應用爆棚了.

那麽讓我們看壹下為什麽會引起這種錯誤:

在Android系統中,壹個App的所有代碼都在壹個Dex文件裏面。Dex是壹個類似Jar的存儲了多有Java編譯字節碼的歸檔文件。因為Android系統使用Dalvik虛擬機,所以需要把使用Java Compiler編譯之後的class文件轉換成Dalvik能夠執行的class文件。這裏需要強調的是,Dex和Jar壹樣是壹個歸檔文件,裏面仍然是Java代碼對應的字節碼文件。當Android系統啟動壹個應用的時候,有壹步是對Dex進行優化,這個過程有壹個專門的工具來處理,叫DexOpt。DexOpt的執行過程是在第壹次加載Dex文件的時候執行的。這個過程會生成壹個ODEX文件,即Optimised Dex。執行ODex的效率會比直接執行Dex文件的效率要高很多。但是在早期的Android系統中,DexOpt有壹個問題,也就是這篇文章想要說明並解決的問題。DexOpt會把每壹個類的方法id檢索起來,存在壹個鏈表結構裏面。但是這個鏈表的長度是用壹個short類型來保存的,導致了方法id的數目不能夠超過65536個。當壹個項目足夠大的時候,顯然這個方法數的上限是不夠的。盡管在新版本的Android系統中,DexOpt修復了這個問題,但是我們仍然需要對低版本的Android系統做兼容.

目前比較常用的方法:(1) 應用插件化,比如使用我正在參與開發的插件化框架 如果有建議或者相關的問題,歡迎到Github上積極參與. (2) 分割Dex,多工程: 把所需要的.class文件或者是Jar文件和壹些源碼壹起編譯生成壹個Jar文件。然後使用Android SDK提供的dx工具把Jar文件轉成Dex文件。我們可以提前對它進行ODex操作,讓它在被DexClassLoader加載的時候,跳過DexOpt的部分工作,從而加快加載的過程. 這兩種方法並不沖突,插件化除了解決應用爆棚,還有很多其他的優點,可以看我之前的文章,不再復述.

當然,Google看來也意識到了目前應用方法數爆棚的問題, 目前在已經在API 21中提供了通用的解決方案,那就是android-support-multidex.jar. 這個jar包最低可以支持到API 4的版本(Android L及以上版本會默認支持mutidex).

讓我們看壹下如何應用android-support-multidex.jar(以下都以在Anroid studio中的使用為例,使用eclipse開發需要安裝gradle插件,其他基本上相同):

首先可以用--multi-dex配置(build.gradle)進行解決,生成的Apk中將包含多個dex文件,比如classes.dex, classes2.dex. 如下,需要對build.gradle進行修改:

[java] view plaincopy

afterEvaluate {

tasks.matching {

it.name.startsWith('dex')

}.each { dx ->

if (dx.additionalParameters == null) {

dx.additionalParameters = []

}

dx.additionalParameters += '--multi-dex' // enable multidex

// optional

// dx.additionalParameters += "--main-dex-list=$projectDir/<filename>".toString() // enable the main-dex-list

}

}

但是默認的Dalvik 類加載器只會尋找classes.dex,所以需要將它們進行合並才能使得被識別

當然,現在有了android.support.multidex.jar的支持,壹切都會變得非常簡單,首先我們看壹下相關源碼的目錄,具體的原理分析我會在之後的文章中進行講解:

[java] view plaincopy

android/support/multidex/BuildConfig.class

android/support/multidex/MultiDex$V14.class

android/support/multidex/MultiDex$V19.class

android/support/multidex/MultiDex$V4.class

android/support/multidex/MultiDex.class

android/support/multidex/MultiDexApplication.class

android/support/multidex/MultiDexExtractor$1.class

android/support/multidex/MultiDexExtractor.class

android/support/multidex/ZipUtil$CentralDirectory.class

android/support/multidex/ZipUtil.class

具體集成:

將如下配置加入工程 classPath中

[java] view plaincopy

repositories {

jcenter()

}

dependencies {

compile 'com.google.android:multidex:0.1'

}

MultiDex實現原理:

Apk在運行的時候,有壹個dexpathlist,而Multidex的源碼中,會根據妳的系統版本號對dexpathlist做修改,將所有的dex都添加到dexpathlist中.

接下來集成有兩個步驟:

壹. 從sdk\extras\android\support\multidex\library\libs 目錄將android-support-multidex.jar導入工程中

二. 如果妳的工程中已經含有Application類,那麽讓它繼承android.support.multidex.MultiDexApplication類,

如果妳的Application已經繼承了其他類並且不想做改動,那麽還有另外壹種使用方式,覆寫attachBaseContext()方法:

[java] view plaincopy

public class MyApplication extends FooApplication {

@Override

protected void attachBaseContext(Context base) {

super.attachBaseContext(base);

MultiDex.install(this);

}

}

最後給出build.gradle中的完整配置:

[java] view plaincopy

buildscript {

repositories {

jcenter()

}

dependencies {

classpath 'com.android.tools.build:gradle:0.13.3'

classpath 'jp.leafytree.gradle:gradle-android-scala-plugin:1.1'

}

}

apply plugin: 'com.android.application'

apply plugin: 'jp.leafytree.android-scala'

repositories {

jcenter()

}

android {

compileSdkVersion 21

buildToolsVersion '21.0.2'

defaultConfig {

applicationId 'some.app'

minSdkVersion 19

targetSdkVersion 19

versionCode 1

versionName '1.0'

}

}

dependencies {

compile 'com.google.android:multidex:0.1'

compile 'com.android.support:support-v4:19.0.1'

compile 'com.google.android.gms:play-services:5.0.77'

compile 'org.scala-lang:scala-library:2.11.2'

compile 'org.scaloid:scaloid_2.11:3.4-10'

}

  • 上一篇:禁止華為中興對美國有什麽好處?
  • 下一篇:濮陽室對於棋牌室得相關規定
  • copyright 2024編程學習大全網