程序包android multidex.support.multidex不存在 是什么原因造成的

Android使用MultiDex处理64K限制 - 胡飞飞的个人博客 - CSDN博客
Android使用MultiDex处理64K限制
随着Android平台的不断发展,Android应用的规模也越来越大。当你的程序以及程序所使用的库达到一定大小,build时可能会产生错误,这表示你的程序已经达到Android应用架构的极限。
老版本构建工具报错:
Conversion to Dalvik format failed:Unable to execute dex: method ID notin[0,0xffff]:65536
新版本构建工具报错:
trouble writing output : Too many field references : 131000 ;max is 65536. You may try using
这两个错误都提到65535,这个数字表示Dalvik字节码文件(也就是DEX文件)中可包含的方法的总数,因为Dalvik虚拟机中以short类型来索引DEX文件中的方法。
如果你的应用出现了这个错误,首先恭喜你,你的应用肯定有很大的代码量。文章接下来就介绍如何解决该问题,让你的应用拥有更大的代码量和更丰富的功能。
在Android5.0之前平台中使用MultiDex
因为Android5.0之前的系统是使用来执行应用程序。默认情况下,Dalvik虚拟机将每个APK限制在单个classes.dex字节码文件中。我们可以使用MultiDex支持库来解决单个Dex文件的限制。
MultiDex的原理:将MultiDex支持库的代码放在主Dex文件中,把超额的方法放在附加Dex文件中,MultiDex支持库负责管理附加Dex文件中的方法,主Dex的函数通过MultiDex支持库去间接调用附加Dex文件中的方法。
Android5.0及以上版本的MultiDex
Androd5.0之后使用了名为的运行时环境,它本身就支持“APK中包含多个dex文件”。
ART在应用安装时执行预编译,将Dalvik字节码翻译成本机二进制机器码从而加快应用执行速度:在预编译过程中会扫描dex文件,并将多个dex文件(dalvik字节码)编译成单个.oat文件(二进制机器码)。关于ART的更多信息,可以参考Android官方文档。
解决65K限制的方法。
1. 避免64K问题——减少方法数
在程序中应尽量避免使用重量型的库,比如Google的Guava,Apache的Commons等。大多数JavaEE中的库都不适合在Android中使用。
使用ProGuard删除未使用的代码,保证应用的发布版本体积尽可能小巧。ProGuard的使用会在后面的文章中提到。
2. 配置MultiDex构建多dex应用
首先确保你使用的Build Tools是21.1及以上版本,因为这样才可以使用Gradle的安卓插件来支持multidex。
步骤如下:
更改Gradle配置以启用MultiDex,示例如下:
compileSdkVersion 21
buildToolsVersion "21.1.0"
defaultConfig {
minSdkVersion 14
targetSdkVersion 21
// 构建时生成多个dex
multiDexEnabled true
dependencies {
// 添加MultiDex支持库的依赖
compile 'com.android.support:multidex:1.0.0'
multiDexEnabled属性可以设置在defaultConfig,buildType或者productFlavor中。
修改应用清单以使用MultiDexApplication类
&?xml version="1.0" encoding="utf-8"?&
xmlns:android="/apk/res/android"
package="com.example.android.multidex.myapplication"&
android:name="android.support.multidex.MultiDexApplication"&
如果你的应用需要在Application中进行初始化,可以继承MultiDexApplication类。示例代码如下:
package cn.hff.A
import android.support.multidex.MultiDexA
public class App extends MultiDexApplication{
public void onCreate() {
&?xml version="1.0" encoding="utf-8"?&
xmlns:android="/apk/res/android"
package="com.example.android.multidex.myapplication"&
android:name="cn.hff.App"&
事实上MultiDexApplication源码很简单:
public class MultiDexApplication extends Application {
public MultiDexApplication() {
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
所以对于上面的App我们还可以这么写:
package cn.hff.A
import android.app.A
public class App extends Application{
public void onCreate() {
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
完成以上配置后,Android构建工具会根据需要将字节码文件打包成一个主Dex文件(classes.dex)和多个附加Dex文件(classes2.dex、classes3.dex…)。
开发过程中对MultiDex程序构建的优化
配置MultiDex后应用构建的时间明显增长,因为构建系统需要判断主Dex文件中应该包含哪些类、辅助Dex文件中应该包含哪些类,这个过程非常复杂。构建MultiDex应用于构建常规应用通常需要更多的时间,这可能会降低你的开发速度。
为了减短MultiDex应用的构建时间,我们可以在Gradle的productFlavors属性中配置两种输出模式:开发模式和发行模式。
开发模式中我们可以将minSdkVersion设置为21(也就是Android5.0),这样应用可以使用ART的格式,从而更快的生成MultiDex的Apk。
发行模式中我们可以将minSdkVersion设置为应用实际需要兼容的最低SDK版本,这个设置可以兼容更低版本的Android平台,但相应地需要更长的构建时间。
一下是Gradle文件中相应的配置。
productFlavors {
// 定义开发模式和发行模式
// 开发模式设置 minSDKVersion = 21 从而允许Android Gradle插件预
// 先将每个模块打包成dex并生成一个可以在Android5.0上测试的APK文件,
// 这样不需要在Dex合并上耗费过多的时间
minSdkVersion 21
// 应用实际需要兼容的最低SDK版本
minSdkVersion 14
buildTypes {
// 发行版运行ProGuard对方法数进行压缩
runProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
dependencies {
compile 'com.android.support:multidex:1.0.0'
参考文章:
Gradle插件用户指南:
我的热门文章解决Android Studio加载第三方jar包,出现包重复加载的问题:
通过Maven中央库添加第三方jar包的时候,出现了重复加载jar包的问题,解决办法很简单去掉一个不让它去加载就OK了
Error:Execution failed for task ':app:dexDebug'.
> com.mon.internal.LoggedErrorException: Failed to run command:
F:\zsl\sdk\build-tools\21.1.2\dx.bat --dex --output F:\zsl\\pro\RecipesDaquan\app\build\intermediates\dex\debug --input-list=F:\zsl\Android\pro\RecipesDaquan\app\build\intermediates\tmp\dex\debug\inputList.txt
Error Code:
UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.DexException: Multiple dex files define Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompatI
at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:596)
at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:554)
at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:535)
at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:171)
at com.android.dx.merge.DexMerger.merge(DexMerger.java:189)
at com.mand.dexer.Main.mergeLibraryDexBuffers(Main.java:454)
at com.mand.dexer.Main.runMonoDex(Main.java:303)
at com.mand.dexer.Main.run(Main.java:246)
at com.mand.dexer.Main.main(Main.java:215)
at com.mand.Main.main(Main.java:106)
从上述错误中我们可以看到support_v4的包重复加载编译了,我们看一下gradle-app文件
vcD4KPHByZSBjbGFzcz0="brush:">dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.0'
compile 'in.srain.cube:cube-sdk:1.0.42.1'
compile files('libs/android-async-http-1.4.6.jar')
}其中引入了v7的包后会自动去加载编译一个v4:21.0.0包,而在in.srain.cube:cube-sdk:1.0.42.1库中也有一个v4的包,所以我们需要去掉一个
看一下,libraries是否是我们所讲的那样,重复加载v4包
二、解决办法
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.0'
compile ('in.srain.cube:cube-sdk:1.0.42.1'){
exclude module: 'support-v4'
compile files('libs/android-async-http-1.4.6.jar')
}去掉in.srain.cube:cube-sdk:1.0.42.1中的包不加载即可。141681人阅读
Android(142)
Anroid L MutiDex
&&&&&&&& 如有转载,请声明出处: 时之沙:&&&& (来自时之沙的csdn博客)&&&&&&&& 随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方sdk或者公共支持的jar包,项目耦合性高,重复作用的类越来越多),相信很多人都遇到过如下的错误: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.mand.dexer.Main.mergeLibraryDexBuffers(Main.java:439)
at com.mand.dexer.Main.runMonoDex(Main.java:287)
at com.mand.dexer.Main.run(Main.java:230)
at com.mand.dexer.Main.main(Main.java:199)
at com.mand.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的LinearAlloc存在着限制:&Android 2.2和2.3的缓冲区只有5MB,Android 4.x提高到了8MB或16MB。当方法数量过多导致超出缓冲区大小时,会造成dexopt崩溃,导致无法安装.&& & & & 另外由于DEX文件格式限制,一个DEX文件中method个数采用使用原生类型short来索引文件中的方法,也就是最多表达65536个method,field/class的个数也均有此限制。对于DEX文件,则是将工程所需全部class文件合并且压缩到一个DEX文件期间,也就是Android打包的DEX过程中, 单个DEX文件可被引用的方法总数被限制为65536(自己开发以及所引用的Android Framework和第三方类库的代码).&&&& && 目前比较常用的方法:(1) 应用插件化,比如使用我正在参与开发的插件化框架 :& ,如果有建议或者相关的问题,欢迎到Github上积极参与. (2) 分割Dex,多工程: 把所需要的.class文件或者是Jar文件和一些源码一起编译生成一个Jar文件。然后使用Android SDK提供的dx工具把Jar文件转成Dex文件。(可参考facebook:,这里边还可以看到在2.3上动态改变的解决思路) 这两种方法并不冲突,插件化除了解决应用爆棚,还有很多其他的优点,可以看我之前的文章,不再复述.&&&&&&& 当然,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进行修改: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的支持,一切都会变得非常简单,首先我们看一下相关源码的目录,具体的原理分析我会在之后的文章中进行讲解: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具体集成:将如下配置加入工程 build.gradle中&android {
defaultConfig {
// Enabling multidex support.
multiDexEnabled true
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()方法:public class MyApplication extends FooApplication {
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}最后给出build.gradle中的完整配置: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'
}使用MutiDex的主意事项一. 如果你继承了MutiDexApplication或者覆写了Application中的attachBaseContext()方法.Application类中逻辑的注意事项:Application 中的静态全局变量会比MutiDex的 instal()方法优先加载,所以建议避免在Application类中使用静态变量引用main classes.dex文件以外dex文件中的类,可以根据如下所示的方式进行修改:@Override
public void onCreate() {
super.onCreate();
final Context mContext =
new Runnable() {
public void run() {
// put your logic here!
// use the mContext instead of this here
二.&虽然Google解决了应用总方法数限制的问题,但并不意味着开发者可以任意扩大项目规模。Multidex仍有一些限制:避免应用过大、方法过多仍然是Android开发者要注意的问题。Mihai Parparita的开源项目dex-method-counts可以用于统计APK中每个包的方法数量。通常开发者自己的代码很难达到这样的方法数量限制,但随着第三方类库的加入,方法数就会迅速膨胀。因此选择合适的类库对Android开发者来说尤为重要。开发者应该避免使用Google Guava这样的类库,它包含了13000多个方法。尽量使用专为移动应用设计的Lite/Android版本类库,或者使用小类库替换大类库,例如用Google-gson替换Jackson JSON。而对于Google Protocol Buffers这样的数据交换格式,其标准实现会自动生成大量的方法。采用Square Wire的实现则可以很好地解决此问题。常见问题DexException: Library dex files are not supported in multi-dex mode,你可能会见到如下的错误:Error:Execution failed for task ':app:dexDebug'.
& com.mon.internal.LoggedErrorException: Failed to run command:
$ANDROID_SDK/build-tools/android-4.4W/dx --dex --num-threads=4 --multi-dex
Error Code:
UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.DexException: Library dex files are not supported in multi-dex mode
at com.mand.dexer.Main.runMultiDex(Main.java:322)
at com.mand.dexer.Main.run(Main.java:228)
at com.mand.dexer.Main.main(Main.java:199)
at com.mand.Main.main(Main.java:103)&对于dex 的--multi-dex 选项设置与预编译的library工程有冲突,因此如果你的应用中包含引用的lirary工程,需要将预编译设置为false:android {
dexOptions {
preDexLibraries = false
OutOfMemoryError: Java heap space当运行时如果看到如下错误:UNEXPECTED TOP-LEVEL ERROR:
java.lang.OutOfMemoryError: Java heap space在dexOptions中有一个字段用来增加java堆内存大小:android {
dexOptions {
javaMaxHeapSize &2g&
使用eclipse的开发人员可以参考Google官方文档需要安装支持gradle构建的插件,下载地址:& (目前可能需要翻墙) 参考相关资料:1. MutiDex 官方文档: 2. 另附android -support-mutidex.jar下载地址:&补充注意事项:com.android.dex.DexException: Multiple dex files define L{package}/BuildC如果遇到这个错误请进行如下检查:1. 主工程与依赖library工程包名是否重复2. 检查主工程与依赖library工程是否含有重复的support.jar或者其他jar包解决方案:1. 修改library工程包名2. 删除重复jar包3.手工添加lib包,增加如下配置dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':lib-project-module')
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3118134次
积分:20264
积分:20264
排名:第408名
原创:197篇
转载:21篇
译文:14篇
评论:1030条
微博: Shawn_Tony
(1)(1)(1)(2)(1)(1)(7)(8)(3)(8)(11)(13)(4)(2)(4)(11)(7)(23)(24)(54)(21)(9)(12)(2)(1)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'前天准备发包了,测试完毕,打好正式签名包,装到手机上,运行不起来。
网上查了大量资料,都没有解决方案。
log显示如下:
04-26 10:07:57.727 /? I/MultiDex: VM with version 2.1.0 has multidex support04-26 10:07:57.728 /? I/MultiDex: install04-26 10:07:57.728 /? I/MultiDex: VM has multidex support, MultiDex support library is disabled.04-26 10:07:57.771 /? D/BitmapCache.initDiskCache(L:101): create disk cache success04-26 10:07:57.850 /? W/WindowAnimator: Failed to dispatch window animation state change.
android.os.DeadObjectException
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:503)
at android.view.IWindow$Stub$Proxy.onAnimationStopped(IWindow.java:534)
at com.android.server.wm.WindowAnimator.updateWindowsLocked(WindowAnimator.java:289)
at com.android.server.wm.WindowAnimator.animateLocked(WindowAnimator.java:681)
at com.android.server.wm.WindowAnimator.access$000(WindowAnimator.java:53)
at com.android.server.wm.WindowAnimator$1.doFrame(WindowAnimator.java:123)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:672)
at android.view.Choreographer.doFrame(Choreographer.java:605)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:846)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.os.HandlerThread.run(HandlerThread.java:61)
at com.android.server.ServiceThread.run(ServiceThread.java:46)04-26 10:07:57.851 /? I/Timeline: Timeline: App_transition_ready time:04-26 10:07:57.856 /? I/Timeline: Timeline: App_transition_ready time:04-26 10:07:57.889 /? I/System.out: imid = null04-26 10:07:57.992 /? D/AndroidRuntime: Shutting down VM
后来调试发现,去掉混淆才可以运行,但是研究MultiDex发现跟混淆没有关系,而是只要获取java.vm.version的版本号是&=2.1就直接结束了安装。
private static final boolean IS_VM_MULTIDEX_CAPABLE = isVMMultidexCapable(System.getProperty("java.vm.version"));
public static void install(Context context)
Log.i("MultiDex", "install");
if (IS_VM_MULTIDEX_CAPABLE) {
Log.i("MultiDex", "VM has multidex support, MultiDex support library is disabled.");
static boolean isVMMultidexCapable(String versionString)
boolean isMultidexCapable =
if (versionString != null) {
Matcher matcher = pile("(\\d+)\\.(\\d+)(\\.\\d+)?").matcher(versionString);
if (matcher.matches()) {
int major = Integer.parseInt(matcher.group(1));
int minor = Integer.parseInt(matcher.group(2));
isMultidexCapable = (major & 2) || ((major == 2) && (minor &= 1));
catch (NumberFormatException localNumberFormatException)
Log.i("MultiDex", new StringBuilder().append("VM with version ").append(versionString).append((isMultidexCapable) ? " has multidex support" : " does not have multidex support").toString());
return isMultidexC
今天早上上班,打开studio ,提示需要升级Gradle版本到2.1.0(原来是2.0.0),然后升级以后,再打包测试了一下,一切又恢复正常了。
然后这个问题是跟Gradle的版本有关,至此这个问题算是解决了。
阅读(...) 评论()随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方sdk
随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方sdk或者公共支持的jar包,项目耦合性高,重复作用的类越来越多),相信很多人都遇到过如下的错误:
没错,你的应用中的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进行修改:
但是默认的Dalvik 类加载器只会寻找classes.dex,所以需要将它们进行合并才能使得被识别当然,现在有了android.support.multidex.jar的支持,一切都会变得非常简单,首先我们看一下相关源码的目录,具体的原理分析我会在之后的文章中进行讲解:
具体集成:将如下配置加入工程 classPath中
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()方法:
最后给出build.gradle中的完整配置:
使用MutiDex的主意事项
一. 如果你继承了MutiDexApplication或者覆写了Application中的attachBaseContext()方法.
Application类中逻辑的注意事项:
Application 中的静态全局变量会比MutiDex的 instal()方法优先加载,所以建议避免在Application类中使用main classes.dex文件中可能使用到的静态变量,可以根据如下所示的方式进行修改:
二. 虽然Google解决了应用总方法数限制的问题,但并不意味着开发者可以任意扩大项目规模。Multidex仍有一些限制:
避免应用过大、方法过多仍然是Android开发者要注意的问题。Mihai Parparita的开源项目dex-method-counts可以用于统计APK中每个包的方法数量。
通常开发者自己的代码很难达到这样的方法数量限制,但随着第三方类库的加入,方法数就会迅速膨胀。因此选择合适的类库对Android开发者来说尤为重要。
开发者应该避免使用Google Guava这样的类库,它包含了13000多个方法。尽量使用专为移动应用设计的Lite/Android版本类库,或者使用小类库替换大类库,例如用Google-gson替换Jackson JSON。而对于Google Protocol Buffers这样的数据交换格式,其标准实现会自动生成大量的方法。采用Square Wire的实现则可以很好地解决此问题。
DexException: Library dex files are not supported in multi-dex mode,你可能会见到如下的错误:
对于dex 的--multi-dex 选项设置与预编译的library工程有冲突,因此如果你的应用中包含引用的lirary工程,需要将预编译设置为false:
OutOfMemoryError: Java heap space当运行时如果看到如下错误:
在dexOptions中有一个字段用来增加java堆内存大小:
使用eclipse的开发人员可以参考Google官方文档
需要安装支持gradle构建的插件,下载地址:
(目前可能需要翻墙)
参考相关资料:
1. MutiDex 官方文档:
另附android -support-mutidex.jar下载地址:
补充注意事项:
如果遇到这个错误请进行如下检查:
1. 主工程与依赖library工程包名是否重复
2. 检查主工程与依赖library工程是否含有重复的support.jar或者其他jar包
1. 修改library工程包名
2. 删除重复jar包
3.手工添加lib包,增加如下配置
版权声明:本文内容由互联网用户自发贡献,本社区不拥有所有权,也不承担相关法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至: 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
用云栖社区APP,舒服~
【云栖快讯】浅析混合云和跨地域网络构建实践,分享高性能负载均衡设计,9月21日阿里云专家和你说说网络那些事儿,足不出户看直播,赶紧预约吧!&&
阿里云移动APP解决方案,助力开发者轻松应对移动app中随时可能出现的用户数量的爆发式增长、复杂的移动安全挑战等...
通过机器学习和数据建模发现潜在的入侵和攻击威胁,帮助客户建设自己的安全监控和防御体系,从而解决因网络攻击导致企业...
是将源站内容分发至全国所有的节点,缩短用户查看对象的延迟,提高用户访问网站的响应速度与网站的可用性,解决网络带宽...
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本...
MaxCompute75折抢购
Loading...

我要回帖

更多关于 android multidex 的文章

 

随机推荐