24

有没有关于“dx”的文档?

特别是,我有兴趣知道该--core-library选项的作用。

4

3 回答 3

38

什么是“dx”工具?

dx工具将Java 类文件转换为*.dexDalvik可执行文件)* 文件。

它在哪里?

dx.jar文件原来位于android-sdk/platforms/android-X/tools/lib/之前(尤其是在Android 3Android 4中),后来被移动到android-sdk/platform-tools/lib/下。

它如何适应 Android?

Java 源文件由Java 编译器转换为Java 类文件。

dx工具将Java 类文件转换为*.dex(Dalvik 可执行文件)* 文件。应用程序的所有类文件都放在这个.dex文件中。在此转换过程中,类文件中的冗余信息在.dex文件中进行了优化。

例如,如果在不同的类文件中找到相同的字符串,则.dex文件只包含对该字符串的一个引用。

因此,这些.dex文件的大小比相应的类文件小得多。

.dex文件和 Android 项目的资源,例如图像和 XML 文件,被打包到一个.apk(Android 包)文件中。

为了更好地理解,请查看 Android 构建过程:

构建过程

供参考:

程序AAPT(Android 资产打包工具执行APK创建。生成的.apk文件包含运行 Android 应用程序所需的所有数据,并且可以通过ADB(Android 设备桥)工具部署到 Android 设备。

参考

于 2014-05-29T15:24:56.893 回答
10

这是一个特殊用途的标志,仅在构建一些框架 JAR 文件(core.jarframework.jar等)时使用。通常,dx 将拒绝处理任何 java.* 或 javax.* 类。所以这个选项用于core.jar,所有这些类都是在其中定义的。

这是来自 dx 源 ( dalvik/dx/src/com/android/dx/command/dexer/Main.java ) 的相关宣传,如果您尝试在应用程序中包含 java.* 或 javax.* 类,则会打印出来.

不构建核心库时对核心类(java.* 或 javax.*)的不明智或错误使用。这通常是由于在使用 IDE(例如 Eclipse)时无意中在应用程序的项目中包含了核心库文件。如果您确定您不是故意定义核心类,那么这是对正在发生的事情的最可能的解释。

但是,您实际上可能正在尝试在核心命名空间中定义一个类,例如,您可能从非 Android 虚拟机项目中获取了该类的源代码。这肯定是行不通的。至少,它会危及您的应用程序与平台未来版本的兼容性。它的合法性也经常受到质疑。

如果你真的打算构建一个核心库——它只适合作为创建完整虚拟机发行版的一部分,而不是编译应用程序——然后使用“--core-library”选项来抑制这个错误消息。如果您继续使用“--core-library”,但实际上正在构建应用程序,那么请预先警告您的应用程序在某些时候仍将无法构建或运行。请为愤怒的客户做好准备,他们会发现,例如,一旦他们升级操作系统,您的应用程序就会停止运行。你会为这个问题负责。

如果您合法地使用了一些恰好位于核心包中的代码,那么您拥有的最简单安全的替代方法是重新打包该代码。也就是说,将有问题的类移动到您自己的包命名空间中。这意味着它们永远不会与核心系统类发生冲突。JarJar 是一个可以帮助您完成这项工作的工具。如果你发现你做不到这一点,那么这表明你所走的道路最终会导致痛苦、痛苦、悲伤和悲叹。

于 2011-12-13T18:35:57.033 回答
4

Dx 上的--core-library选项将绕过可防止您在 Android 应用程序中意外包含 Java 核心库的愚蠢检查。

如果您尝试在java.*javax.*命名空间中包含包含包的库,则 Dx 将失败。想法是该命名空间中的类可能依赖于其他 JDK“核心”类,这会破坏您的应用程序,因为它们(可能)不存在于 Android 上。

现在,当然,仅仅因为 Java 包以java.*javax.*开头并不一定意味着它依赖于适当的 JDK。它在 Android 中可能工作得很好。如果您知道自己在做什么,如果您知道您的 java/x.* 类不依赖于 JDK 核心类,建议是使用 JarJar 之类的工具将 JAR 文件重新打包到不同的命名空间下。

话虽如此,为了绕过愚蠢检查,将--core-library选项添加到 dx. 更改 from 的最后一行$ANDROID_HOME/platform-tools/dx

exec java $javaOpts -jar "$jarpath" "$@"

到,

exec java $javaOpts -jar "$jarpath" --core-library "$@"

就我而言,我包含了一个依赖于Jackson的库,它依赖于JAXB。对我来说,重写愚蠢检查是可以接受的,因为该库对 Jackson 的使用仅用于 JSON 而不是用于 XML 序列化(我只包括 JAXB API 库,而不是实现)。当然,我希望有一种更简洁的方法来解决这个问题,但是重写顶级库以避免使用 Jackson 不是一种选择。

于 2012-06-18T20:54:38.950 回答