有没有关于“dx”的文档?
特别是,我有兴趣知道该--core-library
选项的作用。
dx工具将Java 类文件转换为*.dex(Dalvik可执行文件)* 文件。
dx.jar文件原来位于android-sdk/platforms/android-X/tools/lib/之前(尤其是在Android 3和Android 4中),后来被移动到android-sdk/platform-tools/lib/下。
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 设备。
这是一个特殊用途的标志,仅在构建一些框架 JAR 文件(core.jar、framework.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 是一个可以帮助您完成这项工作的工具。如果你发现你做不到这一点,那么这表明你所走的道路最终会导致痛苦、痛苦、悲伤和悲叹。
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 不是一种选择。