无法使用外部jar包构buildAnt的多个Android dex文件

我正在开发一个需要多个库(对于Facebook,Google Maps v2和Quickblox等)的Android应用程序,导致方法数量溢出超过64K限制:

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

正如我不能没有任何这些库,我寻找一个解决方法的限制错误。 我从Android开发者那里发现了一个受欢迎的博客条目,推荐使用源代码部门。 (我在说的博客条目可以在这里find: http : //android-developers.blogspot.com.es/2011/07/custom-class-loading-in-dalvik.html )。 我一直在尝试这个解决scheme,但没有成功。

我现在的问题是,最大的代码量不是在我的应用程序本身,而是在所需的库中,所以我必须将这些库扩散到我的应用程序中必须加载的不同dex文件中。 我对Ant的知识是非常有限的,我想知道的是我应该在我的build.xml文件中写入dex复制每个我想要的库:

  <!-- Primary dex to include my source code and some libraries. --> <copy todir="${out.classes.absolute.dir}.1" > <fileset dir="${out.classes.absolute.dir}" > ... </fileset> </copy> <!-- Secondary dex to include some other libraries. --> <copy todir="${out.classes.absolute.dir}.2" > <fileset dir="${out.classes.absolute.dir}" > ... </fileset> </copy> 

任何帮助将是真正的赞赏。 在此先感谢,亲切的问候!

Solutions Collecting From Web of "无法使用外部jar包构buildAnt的多个Android dex文件"

我听到这个问题到目前为止最好的答案是使用ProGuard优化模式(proguard-android-optimize.txt)与-dontobfuscate标志从最终APK(不混淆它们)删除未使用的类和方法。 然后,您可以使用ProGuard mapping.txt来帮助您将未使用的类从您使用的库JAR中剥离出来(我不知道这是一个好工具)。 不幸的是,我不认为ProGuard中有一项function可以自动执行此操作。

ProGuard只在Eclipse中执行导出时运行,而不是在运行时执行 – > Android应用程序。 这意味着它不会帮助避免debugging版本的限制,除非您使用自定义构build过程。 ProGuard的创build者build议使用它的商业兄弟DexGuard ,它将在Eclipse中运行在debugging和发布版本上。

强烈build议使用ProGuard进行发布版本,因为它会减less代码大小,提高性能(例如通过内联代码),也会混淆源代码。 确保你在最后一个APK上做了足够的testing,因为它与debugging版本有很大的不同。 不幸的是,ProGuard本身还不足以解决我的问题,所以我删除了一个JAR依赖关系作为解决方法。

我使用这个命令检查了依赖JAR中的方法数量:

 dx --dex --output=temp.dex library.jar cat temp.dex | head -c 92 | tail -c 4 | hexdump -e '1/4 "%d\n"' 

示例我们最大的图书馆的方法数量:

 11222 guava-11.0.1.jar 10452 aws-android-sdk-1.5.0-core.jar 5761 org.restlet.jar 5129 protobuf-java-2.4.1.jar 2499 aws-android-sdk-1.5.0-s3.jar 2024 ormlite-core-4.41.jar 1145 gson-2.2.2.jar 1716 google-http-client-1.11.0-beta.jar 

仅供参考,您可以使用dexdump(您可以在SDK build-tools文件夹中find,例如“Android Studio.app/sdk/build-tools/21.0.2/dexdump”)来检查APK中的方法数量:

 dexdump -f MyApp.apk | grep method_ids_size method_ids_size : 64295 

在我们的情况下,我们只使用番石榴进行YouTubesearch,所以很容易消除这种依赖,给我们更多的喘息空间。

更新:我发现从大JAR中去掉未使用的代码最简单的方法是在Proguard构build中使用dex2jar,然后使用JD-GUI将最终的JAR与我想修剪的特定inputJAR进行比较。 然后我删除了我知道被Proguard删除的顶级包。 这使我可以从aws-android-sdk-1.5.0-core.jar中移除> 8000个方法。

ProGuard是一个源代码缩小工具,它将在打包应用程序时删除任何未使用/重复的类。 所以即使使用所有这些外部JAR,也不会100%使用这些内部的所有类,而且这些JAR中的很多可以有相同的类(例如Log4J等)。

Proguard被build成dex 。 但是默认情况下它不会被激活,你必须在发布模式下运行ant,并且你可能还必须在project.properties中注释掉一行。

最有可能的是,ProGuard最终可能会删除您的应用程序中使用的一些类。 如果在编译ProGuard时遇到class X not found错误,请在proguard.cfg中configurationProGuard,您需要该类:

 -keep public class <full path to the class that you need> 

查看Android ProGuard文档,看看启用proguard是否会减小APK中的大小(类和方法)。