无法与蚂蚁从外部罐构建多个Android的DEX文件 [英] Can't build multiple Android dex files with Ant from external jars

查看:231
本文介绍了无法与蚂蚁从外部罐构建多个Android的DEX文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发一个Android应用程序需要多个库(其中包括Facebook,谷歌地图v2和Quickblox),导致方法量溢出,从而越过64k的限制:

I'm developing an Android app that requires multiple libraries (for Facebook, Google Maps v2 and Quickblox among others), resulting in a method amount overflow that goes over the 64K limit:

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开发者,其中一个源$ C ​​$ C师建议一个受欢迎的博客条目。 (博客条目我说的可以在这里找到:<一href="http://android-developers.blogspot.com.es/2011/07/custom-class-loading-in-dalvik.html">http://android-developers.blogspot.com.es/2011/07/custom-class-loading-in-dalvik.html).我一直在想这个解决方案没有成功。

As I can't do without any of those libraries, I looked for a solution for the method limit bug. I found a popular blog entry from Android Developers, where a source code division is recommended. (The blog entry I'm talking about can be found here: http://android-developers.blogspot.com.es/2011/07/custom-class-loading-in-dalvik.html). I've been trying this solution with no success.

这个问题我现在是,code的最大金额是不是在我的应用程序本身,而在于所需要的库,所以我必须向S $ P $垫不同的DEX文件,我必须加载在那些库在我的应用程序。我的Ant的知识非常有限,我想知道的是什么,我应该写在我的build.xml文件,使地塞米松拷贝每一个图书馆,在那里我想要的:

The problem I have now is that the biggest amount of code is not in my app itself, but in the required libraries, so I have to spread those libraries among the different dex files I must load in my app. My knowledge of Ant is very limited, and what I'd like to know is what I should write in my build.xml file to make dex copy each library where I want:

            <!-- 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>

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

Any help would be truly appreciated. Thanks in advance, kind regards!

推荐答案

我已经听到这个问题迄今最好的答案就是使用ProGuard的优化的模式(ProGuard的,Android的optimize.txt)与 -dontobfuscate 标志除去从最终的APK未使用的类和方法(不混淆它们)。然后你可以使用ProGuard的mapping.txt帮你带的未使用的班列,你使用(我不知道的一个很好的工具来做到这一点)的库JAR的。不幸的是,我不认为这是一个特点在ProGuard的自动做到这一点。

The best answer I have heard to this problem so far is to use ProGuard in optimized mode (proguard-android-optimize.txt) with the -dontobfuscate flag to remove unused classes and methods from the final APK (without obfuscating them). Then you can use the ProGuard mapping.txt to help you strip the unused classes out of the library JARs that you use (I'm not aware of a good tool to do this). Unfortunately I don't think there is a feature in ProGuard to do this automatically.

ProGuard的只是在Eclipse中做一个出口时,做一个运行方式而不是当运行。这意味着它不会有助于避免在调试版本,除非您使用自定义生成过程的极限。 ProGuard的的创建者建议使用其商业兄弟 DexGuard ,这将在Eclipse上都调试运行,并发布版本。

ProGuard only runs when doing an Export in Eclipse, not when doing a Run As -> Android Application. This means it won't help avoid the limit on debug builds, unless you use a custom build process. The creator of ProGuard suggests using its commercial sibling DexGuard, which will run in Eclipse on both debug and release builds.

使用ProGuard的大力鼓励的发布版本,因为它会降低你的code尺寸,提高性能(例如,通过内联code),并会混淆你的来源了。确保你做足够的测试在最后的APK因为这将是截然不同的调试之一。不幸的是,ProGuard的自身不足以解决我的问题,所以我删除我的一个JAR依赖作为一种解决办法。

Using ProGuard is strongly encouraged for release builds as it will reduce your code size, improve performance (e.g. by inlining code), and will obfuscate your source too. Make sure you do enough testing on the final APK as it will be dramatically different to the debug one. Unfortunately, ProGuard on its own wasn't enough to solve my problem, so I removed one of my JAR dependencies as a workaround.

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

I checked the number of methods in my dependent JARs using this command:

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

对我们最大的图书馆法的例子号:

Examples numbers of methods for our biggest libraries:

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发现检查您的APK的方法数集结工具文件夹,如机器人Studio.app / SDK /集结工具/ 21.0.2 / dexdump):

FYI, you can check the number of methods in your APK using dexdump (which you can find in your SDK build-tools folder, e.g. "Android Studio.app/sdk/build-tools/21.0.2/dexdump"):

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

在我们的例子中,我们只用番石榴做YouTube的搜索,所以很容易消除这种依赖,给我们更多的喘息空间。

In our case we were only using Guava for doing YouTube searches, so it was easy to remove that dependency and give us more breathing room.

更新:我发现剔除未使用code从大罐子最简单的方法是使用dex2jar我的Proguard的构建,然后使用JD-GUI到最终的JAR比较的具体输入JAR我想修整。然后我删除,我知道获得由Proguard的去除顶层包。这让我删除> 8000的方法从AWS-Android的SDK-1.5.0-core.jar添加。

Update: I found the easiest way to strip out unused code from large JARs was to use dex2jar on my Proguard build, then use JD-GUI to compare that final JAR with the specific input JAR I wanted to trim. Then I remove top level packages that I know get removed by Proguard. This allowed me to remove >8000 methods from aws-android-sdk-1.5.0-core.jar.

这篇关于无法与蚂蚁从外部罐构建多个Android的DEX文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆