Android的'dx'工具

24

有没有“dx”的文档?

我特别想知道--core-library选项的作用。

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 类文件

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

例如,如果在不同的类文件中发现相同的字符串,则 .dex 文件仅包含该字符串的一个引用。

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

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

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

Build process

注意:

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

参考资料


3
最后,是apkbuilder还是aapt创建了APK文件?如果是aapt,那么这个图表就是错误的。 - Shailen
但是图片中似乎是“dex”。也许在你的回答中解释一下这个差异?例如,“Dex”或“dex”是真正的名称,而“dx”是可执行文件的名称?也许还可以提供一个权威的链接来介绍“dx”,比如它的主页(或类似的网站)? - Peter Mortensen

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是一种可以帮助你实现这一目标的工具。如果你发现自己无法做到这一点,那么这就意味着你走的道路最终将导致痛苦、苦难、悲伤和哀悼。


4

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

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

当然,仅仅因为一个Java包以java.*javax.*开头并不一定意味着它依赖于JDK本身。它在Android上可能完全正常工作。建议是,如果您知道自己在做什么,并且知道您的java/x.*类不依赖于JDK核心类,则使用像JarJar这样的工具将JAR文件重新打包到不同的命名空间下。

话虽如此,要绕过愚蠢检查,请将--core-library选项添加到dx中。将$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并不是一个选项。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接