Eclipse 65535 问题解决方案

#

Eclipse 65535 问题解决方案

  最近在工作时碰到了android 65535 方法数超标的问题,把我搞得焦头烂额,关键是公司系统打包用的是ant命令行,androidStudio里一行代码就能搞定,可是没了AS,那也得搞啊。关键时刻在博客园看到了[章鱼的博客](https://www.cnblogs.com/liemng/p/5982221.html),介绍了关于Eclipse 65535 方法数问题的解决办法,受益匪浅但也有一些坑要在这里说下。

  首先说一下解决 65535 方法数问题的本质,简单来讲,第一步通过脚本将一些代码打成一个dex,两个dex,重命名为classes2.dex classes3.dex,然后放到**src**目录下,eclipse as等打包工具打包编译时会自动把这些文件放到跟classes.dex文件同级目录,然后需要用到一个Google出的一个官方的库 **multidex**(获取方法下边会讲) ,导入jar包或者依赖,在Application 的 **attachBaseContext()** 方法中调用 **MultiDex.install(Context);**方法,这句代码内部会利用 ClassLoader ,去 apk 里边找到 classes2.dex 等dex并处理缓存,然后APP就可以正常使用了。

  说了这么多其实只有两步,第一通过脚本生成dex文件,第二通过jar包在运行时动态加载dex文件,AS里边生成dex文件是通过gradle脚本自动完成的,只需要加上一句: ```gradle defaultConfig { ... minSdkVersion 14 targetSdkVersion 21 ...

    // Enabling multidex support.
    multiDexEnabled true
}

而第二步则是使用依赖:
```gradle
	dependencies {
	  compile 'com.android.support:multidex:1.0.0'
	}

并且继承 MultiDexApplication 或重写 attachBaseContext()方法:

	import android.support.multidex.MultiDex;
	public class MyApp extends Application{
		@Override
		protected void attachBaseContext(Context base) {
		    super.attachBaseContext(base);
		    MultiDex.install(this);
		}
	}

  下面进入正题,在 eclipse 或者 ant 命令行编译的环境下我们无法使用方便的 gradle 脚本来自动生成 dex ,所以需要我们通过ant 脚本来手动生成,当然第二步都是一样的。

  首先需要下载 ant脚本,附上超链接点这,然后配置 ANT_HOME 环境变量,具体配置自行百度,其次我们将工程里用的一些方法数比较多的 jar 包拿出来,那么现在有个问题,怎么看方法数多少呢?这个其实无所谓,把比较大的揪出来,jar包总大小大概在8M左右就可以了,再打就超过65535合不了dex了。把这些 jar 包放到某文件夹里 , 比如放在 D:\lib2 文件夹里,然后在当前文件夹新建一 txt 文件, 改名 build.xml 然后在 xml 中加入以下代码:

	<?xml version="1.0" encoding="utf-8"?> 
	<project name="b" basedir="E:\libs\all" default="makeSuperJar"> 
		<target name="makeSuperJar"  description="description"> 
		    <jar destfile="all.jar"> 
		        <zipfileset src="Android_Location_V1.1.2.jar"/>  
		        <zipfileset src="Android_Map_2.1.4.jar"/>         
		        <zipfileset src="Android_Services_2.1.4.jar"/>
		        <zipfileset src="commons-net-3.3.jar"/>
		        <zipfileset src="gson-2.2.1.jar"/>
		    </jar> 
		</target>
	</project>

其中 basedir 为 jar 包存放目录,destfile 为生成jar包的名字,zipfileset src属性则是jar包名字,配置好后保存关闭在当前文件夹内按下shift同时按鼠标右键,选择在此处打开命令窗口,输入指令 ant 如下图

按下回车等一会查看libs目录是否生成一个all.jar包,该jar相当于将刚才xml中配置jar包进行了合并生成一个jar包,接下来需要将该jar包生成dex文件,需要用到一个工具 dx.bat,这个工具在 sdk/build-tools/版本号/dx.bat 中有,在目录 sdk/build-tools/版本号 下shift+右键在此处打开命令窗口,输入命令:dx --dex --output=E:\libs\classes2.dex E:\libs\all.jar,其中 output 为dex生成位置,第二个路径为刚才生成的all.jar的位置,如果顺利的话会生成一个dex文件,将该文件重命名为classes2.dex,如果生成dex文件的时候提示方法数超过65535的错误,请去掉一些jar包,重新合并all.jar,然后再打dex文件。如果打完dex文件工程内还有大量jar包,即还是会有65535的问题,请重复以上步骤,将其余jar打成dex文件并重命名 classes3.dex、classes4.dex。


  然后需要将classes2.dex、classes3.dex、classes4.dex复制到工程src目录下,看起来有点奇怪,但放到这就对了,还没完,接着还需要一个 MultiDex 的库,这个库是Google官方出的库,所以SDK中是有的,在 sdk\extras\android\m2repository\com\android\support目录下(如下图),如果没有请更新SDK或者到网上下载。

打开 multidex 文件夹,里边是版本号,选择一个打开,有一个multidex.arr文件,如下图,用压缩软件打开,将里边classes.jar复制出来,改下名比如 multidex.jar,放到工程libs目录下,然后剩下的步骤就和AndroidStudio一样了,需要在Application中的attachBaseContext方法中调用 MultiDex.install(this);


  OK,截止目前所有的步骤已经搞完了,当然需要将手动打入dex中的jar包删掉,不出意外再次编译时。。。。。。会编译不过,会提示找不到某些类,你会发现这些类就是刚才打到dex中,在工程中删除的类。为什么会出现这个问题呢?其实在Java文件编译成.class文件时,会查找这些java文件中用到的类,比如你在A.java中用了OkHttp的jar 包中的某个类,编译A.java时会查找你又没有用到OkHttp的类,发现你用到了,去找OkHttp文件,但是你这个文件打到dex中了,访问不到,当然就报错了。


  解决办法有两种,第一种:比如工程用到了OkHttp,需要导入两个jar包,一个是OkHttp.jar,另一个是okio.jar,OkHttp.jar工程直接引用了,那就不把他打到dex中,仅仅把okio.jar打入dex中,因为okio.jar没有直接引用,所以编译不会报错。顺便提一下,jar包中引用另一个jar但该被引用的jar又不存在,此时编译不会检测,因为仅仅java 转 class文件才会检测,而jar中的类本身都是.class文件。


  但是现在又有一个问题了OkHttp.jar 300kb,而okio.jar只用30kb,我把未直接引用的jar打到dex中,剩下的代码总方法数还是超过65535了,因为打进classes2.dex中的文件特别少,大部分还是没提取出来。没关系,第一种方法解决不了问题,还有第二种。


  刚才我也说了,仅仅java转class的时候才会检测代码中引用的文件,假如我都是jar包,没有java代码呢?Ok,我现在在src目录下写了好多java 代码,假如我通过某种方法将这里java文件整成一个jar包,放到libs下,那编译的时候就不会报错了,当然不用全部都整成jar文件,只用把那些用到 classes2.dex 中的类的java文件打成jar文件即可,关于怎么打jar包,我是用的AndroidStudio,新建lib工程,将java代码跟jar包都复制进去(包括打入dex中的jar包),点击小锤子按钮build下,过一会在build/outputs/arr 目录下生产一个 arr 文件,解压根目录的 classes.jar就是你想要的jar包,eclipse应该也能,不过我没试过,没AndroidStudio的自行百度怎么生成jar包。

![](https://img-blog.csdnimg.cn/img_convert/22bcf0bab41b4ea5b968404870e92f9f.png)

  还有几个坑我需要说下,在使用AndroidStudio生成jar文件后,请注意,请删除jar包中除了.class文件之外的其他文件,以免出现什么问题(我就出了问题),假如你打成jar包后还是编译不过,请注意我接下来要说的问题:

  当你把src中部分文件打入jar包,然后加入该jar包后编译报错,提示你某个类找不到,请看这个类是否是你打入dex中的类,然后顺着报错的地方找到代码,我举个例子,当你把jar B 打入dex中,有代码直接引用jarB 所以你把这些代码打入 jar A ,然后你还有java代码调用jarA,然后调用的jarA中的这个类继承了jarB的某个类,并且你调用的这个方法jar A中没有重新,然后编译器就会找他的父类,然而这个类在B中并且被打入dex所以找不到,然后就报错。

  解决办法有两种,第一种是把jarB从dex中拿出来放到libs目录下,就不会出现找不到的情况了,还有一种就是修改A中的这个类,并重写父类中的调用的方法如下: ```java class A extends B{ @Override public void b(){ super.b(); } } ``` 不过这种方法我还没有尝试,如果你碰到这种情况了可以尝试一下,理论上是没有问题的。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值