Android应用解决65K方法数限制

近日,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中描述了三种可选方法:

在AndroidManifest.xml的application中声明android.support.multidex.MultiDexApplication;

如果你已经有自己的Application类,让其继承MultiDexApplication;

如果你的Application类已经继承自其它类,你不想/能修改它,那么可以重写attachBaseContext()方法:

@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仍有一些限制:

DEX文件安装到设备的过程非常复杂,如果第二个DEX文件太大,可能导致应用无响应。此时应该使用ProGuard减小DEX文件的大小。

由于Dalvik linearAlloc的Bug,应用可能无法在Android 4.0之前的版本启动,如果你的应用要支持这些版本就要多执行测试。

同样因为Dalvik linearAlloc的限制,如果请求大量内存可能导致崩溃。Dalvik linearAlloc是一个固定大小的缓冲区。在应用的安装过程中,系统会运行一个名为dexopt的程序为该应用在当前机型中运行做准备。dexopt使用LinearAlloc来存储应用的方法信息。Android 2.2和2.3的缓冲区只有5MB,Android 4.x提高到了8MB或16MB。当方法数量过多导致超出缓冲区大小时,会造成dexopt崩溃。

Multidex构建工具还不支持指定哪些类必须包含在首个DEX文件中,因此可能会导致某些类库(例如某个类库需要从原生代码访问Java代码)无法使用。

避免应用过大、方法过多仍然是Android开发者要注意的问题。Mihai Parparita的开源项目dex-method-counts可以用于统计APK中每个包的方法数量。

通常开发者自己的代码很难达到这样的方法数量限制,但随着第三方类库的加入,方法数就会迅速膨胀。因此选择合适的类库对Android开发者来说尤为重要。

开发者应该避免使用Google Guava这样的类库,它包含了13000多个方法。尽量使用专为移动应用设计的Lite/Android版本类库,或者使用小类库替换大类库,例如用Google-gson替换Jackson JSON。而对于Google Protocol Buffers这样的数据交换格式,其标准实现会自动生成大量的方法。采用Square Wire的实现则可以很好地解决此问题。

时间: 2024-10-10 01:49:49

Android应用解决65K方法数限制的相关文章

Android应用打破65K方法数限制

随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方sdk或者公共支持的jar包,项目耦合性高,重复作用的类越来越多),相信很多人都遇到过如下的错误: <span style="color:#ff0000;">UNEXPECTED TOP-LEVEL EXCEPTION: java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536 at com.android.dx.merge

android 方法数超过65k,解决dex方法数超过65536

最近有朋友在问我,为什么我就加了一个类/一个库突然跑不起来了. 排查方式: 1.确认你的代码/引用没有问题 2.检查是否是65k问题 今天主要是解决 排查方式2的步骤,这个原因主要是因为你的apk包方法数过大. 现在解决这个已经很方便了: 方式一(繁琐):程序分包,这个比较繁琐:需要对jvm加载Class的方式有足够的了解 方式二(快速,使用AS): 1.使用google提供的分包库 implementation 'com.android.support:multidex:1.0.2' impl

android 傻瓜式 MultiDex 插件,从此再也不用担心方法数问题!

ndroid-Easy-MultiDex 项目地址:TangXiaoLv/Android-Easy-MultiDex 简介:Android 傻瓜式 MultiDex 插件,从此再也不用担心方法数问题! 注 1:不想看前半部分的话可以直接跳过到最下面配置部分.注 2:本插件是基于DexKnifePlugin 1.5.6优化改造而来,感谢 ceabie 的无私奉献. 填坑之路 坑 1:65536 ,So easy! 原因:Dalvik 的 invoke-kind 指令集中,method refere

安卓应用方法数超过64k解决办法:分割Dex

你的安卓项目功能很强大,对接了好多第三方开源库,项目越做越完善,代码越敲越爽.可是突然有一天报异常了. 错误:The number of method references in a .dex file cannot exceed 64K. 编译器提醒你,你的项目方法数超过64k了. AndroidStudio会提醒你: Learn how to resolve this issue at https://developer.android.com/tools/building/multidex

彻底解决Android 应用方法数不能超过65K的问题

尊重原创 :http://blog.csdn.net/yuanzeyao/article/details/41809423 作为一名Android开发者,相信你对Android方法数不能超过65K的限制应该有所耳闻,随着应用程序功能不断的丰富,总有一天你会遇到一个异常: Conversion to Dalvik format failed:Unable toexecute dex: method ID not in [0, 0xffff]: 65536 可能有些同学会说,解决这个问题很简单,我们

解决Android 应用方法数不能超过65K的问题

作为一名Android开发者,相信你对Android方法数不能超过65K的限制应该有所耳闻,随着应用程序功能不断的丰富,总有一天你会遇到一个异常: Conversion to Dalvik format failed:Unable toexecute dex: method ID not in [0, 0xffff]: 65536 可能有些同学会说,解决这个问题很简单,我们只需要在Project.proterty中配置一句话就Ok啦, dex.force.jumbo=true 是的,加入了这句话

Android 使用android-support-multidex解决Dex超出方法数的限制问题,让你的应用不再爆棚

如有转载,请声明出处: 时之沙: http://blog.csdn.net/t12x3456    (来自时之沙的csdn博客) 随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方sdk或者公共支持的jar包,项目耦合性高,重复作用的类越来越多),相信很多人都遇到过如下的错误: UNEXPECTED TOP-LEVEL EXCEPTION: java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 6553

使用android-support-multidex解决Android方法数超过65535的问题

随着应用不断更新,业务的不断增加, 应运而生的应用可能需要集成了各种第三方library,相信很多人都遇到过如下类似的错误: 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.

转: Android 使用android-support-multidex解决Dex超出方法数的限制问题

转自: 时之沙: http://blog.csdn.net/t12x3456 随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方sdk或者公共支持的jar包,项目耦合性高,重复作用的类越来越多),相信很多人都遇到过如下的错误: [java] view plaincopy UNEXPECTED TOP-LEVEL EXCEPTION: java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536 at