您的位置:首页 > 编程语言 > Java开发

UNEXPECTED TOP-LEVEL EXCEPTION: java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65

2016-07-20 17:53 323 查看
UNEXPECTED TOP-LEVEL EXCEPTION: java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536

应用中的Dex 文件方法数超过了最大值65536的上限

那么让我们看一下为什么会引起这种错误:

        在Android系统中,一个App的所有代码都在一个Dex文件里面。Dex是一个类似Jar的存储了多有Java编译字节码的归档文件。因为Android系统使用Dalvik虚拟机,所以需要把使用Java Compiler编译之后的class文件转换成Dalvik能够执行的class文件。这里需要强调的是,DexJar一样是一个归档文件,里面仍然是Java代码对应的字节码文件。当Android系统启动一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOptDexOpt的执行过程是在第一次加载Dex文件的时候执行的。这个过程会生成一个ODEX文件,即Optimised
Dex
。执行ODex的效率会比直接执行Dex文件的效率要高很多。但是在早期的Android系统中,DexOpt有一个问题,也就是这篇文章想要说明并解决的问题。DexOpt会把每一个类的方法id检索起来,存在一个链表结构里面。但是这个链表的长度是用一个short类型来保存的,导致了方法id的数目不能够超过65536个。当一个项目足够大的时候,显然这个方法数的上限是不够的。尽管在新版本的Android系统中,DexOpt修复了这个问题,但是我们仍然需要对低版本的Android系统做兼容.

        目前比较常用的方法:(1) 应用插件化,比如使用我正在参与开发的插件化框架 : https://github.com/singwhatiwanna/dynamic-load-apk ,如果有建议或者相关的问题,欢迎到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).

以上内容转载自http://blog.csdn.net/t12x3456/article/details/40837287,并且博客中讲解了使用androidstudio开发android时,应用android-support-multidex.jar,配置build.gradle文件来解决方法数超限。

   由于现在很多还在使用eclipse,所以也试着下载eclipse的gradle插件来解决方法数超限问题,目前仍未成功。但是跳过gradle配置文件来看本质,其实就是将项目中一个dex文件分成了多个dex文件,然后在安装程序运行时class.dex中Application会去加载其他dex文件。由此可以设想将android项目中的部分jar包打包成dex文件,并命名为classes2.dex,然后放入项目中,在打包时会一并打入apk文件,而打包为classes2.dex的jar包则使用编译依赖到工程中(例如android.jar)。具体做法是:

    1、先将引用的jar包合并打包为dex文件,并命名为classes2.dex

        合并jar : 手动合并:将jar包解压放入同一文件夹,将此文件夹命名为.jar

                      使用ant合并:需要配置ant环境,然后新建build.xml文件(下面是xml内容)

                                命令行输入:ant -buildfile 路径\
4000
build.xml

                        

                   <?xml version="1.0" encoding="utf-8"?>  

                            <project name="b" basedir="E:\libs" default="makeSuperJar">  

                            <target name="makeSuperJar"  description="description">  

                                <jar destfile="all.jar">  

                                        <zipfileset src="activation.jar"/>   

                                        <zipfileset src="additionnal.jar"/>          

                                        <zipfileset src="alipaysdk.jar"/>  

                                </jar>  

                            </target>  

                            </project>

                        然后将合并后的jar通过sdk中的dx命令转为dex文件

        注:Application 中的静态全局变量会比MutiDex instal()方法优先加载,所以建议避免在                                    Application类中使用引用classes2.dex文件的静态变量

      2、将classes2.dex文件复制到你主工程的src目录下,这样在打包时会一并打入apk中。          

      3、将步骤1中的合并jar文件依照android,jar方式引入,这样在打包时就不会打入apk

  通过以上三步就可以解决eclipse中问题:Unable to execute dex: method ID not in [0, 0xffff]: 65536

转载至:http://my.oschina.net/u/992018/blog/354513
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: