精简google-play-services.jar的方法(解决65536问题的应急方案)

更新:官方提供的打包方法 —— http://blog.csdn.net/liuweiballack/article/details/49786211
因为项目功能的需求,需要引入较多的第三方的jar包,但在打包过程中,发生如下错误:

Conversion to Dalvik format failed:Unable to execute dex: method ID not in [0, 0xffff]: 65536

应用中的方法数超过了最大限制,这是因为单个DEX文件可被引用的方法总数(自己开发的代码以及所引用的Android框架、类库的代码)被限制为65536。
【精简google-play-services.jar的方法(解决65536问题的应急方案)】一般我们自己所写的代码,方法数基本上都比较少,远远达不到最大方法数。原因大多是第三方的代码所致,对项目引用的jar包进行查看,发现最新的google_play_service.jar达到了5289KB,其他的jar文件大多都在1000KB以下,查看google_play_services中代码发现,google为了方便用户使用其服务,将google服务都写入到一个文件中。
精简google-play-services.jar的方法(解决65536问题的应急方案)
文章图片

但在平时的使用过程中,可能仅使用到了少部分google服务,因此我们可以根据需求对google_play_services.jar进行精简,只引入我们自己需要的功能即可。
在github上提供了一个用gradle对google_play_services.jar进行重新打包的方法,
https://gist.github.com/dmarcato/d7c91b94214acd936e42
其中最重要的过程如下:
task repack(){ tasks.create(name: "stripPlayServices", type: Jar) { destinationDir = new File("..\\app\\")//生成新的jar包的存储位置 archiveName = "google-play-services_shrink.jar" //新jar包的名称 from(zipTree(new File("google-play-services.jar"))) { //用到的package include "com/google/ads/**" include "com/google/android/gms/ads/**" } }.execute() }

在上面的代码中,假设我们只用到了google的广告功能,我们引入有关ads的package即可(实际上这是正常不能运行的,因此有一些功能的基础功能的package没有添加进来,这里只是做一个简单的示例)。
如果我们要使用大部分功能,需要剔除部分不需要的功能,则将include修改为exclude即可。
在Terminal中运行 gradle repack,生成名为“google-play-services_shrink.jar”的jar包, 其大小仅为364KB,其代码中仅有ads下的文件。
精简google-play-services.jar的方法(解决65536问题的应急方案)
文章图片

虽然这种方法可以大大减少app最终的方法数量,但是随着app功能的增加,终究还是逃不过65536的问题。最好的解决方法是采用google推荐的MultiDex或者使用插件化的方法。
但是,在时间紧急的情况下,这不失为一种应急方法,效果还是比较显著的。

    推荐阅读