我的理解是,Google不喜欢Oracle在Java中使用JRE的许可策略,因此它只是使用自己的JVM规范重写了JRE,该规范模仿JRE,但行为略有不同,特别是在提高效率和安全性方面。
因此,如果我的理解是正确的,这意味着当javac在某些Java源代码上运行并编译成“二进制”byetcode时,兼容的JVM将解释与Dalvik不同的字节码(在某些情况下)。这是Dalvik与其他(兼容)JVM之间固有的区别。
如果到目前为止我说的是不正确的话,请从纠正我开始!
现在,如果Android附带了自己的编译器(可能),并以与javac不同的(与Dalvik兼容的)方式编译Java源代码,那么我就能理解为什么某些代码(没有使用Android编译)不会在Android设备上运行:
MySource.java --> javac --> MySource.class (JRE-compliant) --> JVM --> running Java app
MySource.java --> android-compiler --> MySource.class (Dalvik-compliant) --> Dalvik JVM --> running Android app但是,看起来您使用javac来编译安卓应用程序!?看起来我们有这样的:
MySource.java --> javac --> MySource.class (JRE-compliant) --> JVM --> running Java app
MySource.java --> javac --> MySource.class (JRE-compliant) --> Dalvik JVM --> running Android app (???)如果使用javac将所有源代码编译成字节码,那么为什么Dalvik不能运行某些类型的Java代码?
昨天我问了一个非常类似的问题,虽然技术上回答了这个问题(在重新阅读我的问题之后,我发现我的问题不够具体),但没有人能够解释Dalvik的固有特性是什么,这使得无法从Google或Apache这样的项目中运行Java代码。我被告知,为了让骆驼在Dalvik上运行,我必须获得Camel的源代码,然后它必须“使用Android构建”,但我无法弄清楚这意味着什么或暗示了什么。
例如,对于Camel,您可以这样做(简化):
RouteBuilder.java --> javac --> RouteBuilder.class --> jartool --> camel-context-2.9.jar --> JVM --> running Camel ESB
RouteBuilder.java --> javac --> RouteBuilder.class --> jartool --> camel-context-2.9.jar --> Dalvik JVM --> doesn't work !!! (???)显然,Dalvik JVM内部发生了一些事情,阻止了它运行某些类型的Java代码。--我正在尝试理解当“输入”到Dalvik .时哪些类型的Java代码不会运行。
编辑:在之前“但骆驼3.0将运行在安卓!”我知道-不是我的问题!
发布于 2012-07-07 11:27:29
我正在尝试理解当“输入”到Dalvik时哪些类型的Java代码不会运行。
Dalvik在以下方面与其他JVM不同:
发布于 2012-07-07 11:28:14
如果到目前为止我说的是不正确的话,请从纠正我开始!
嗯,嗯.
javac的字节码被交叉编译成Dalvik字节码,作为Android应用程序构建过程的一部分。Java不能执行Dalvik字节码,就像它可以执行/dev/random的输出一样;类似地,Dalvik不能执行Java字节码。Here is a blog post of mine来自大约两年前,这将涉及到更多的问题。
如果使用javac将所有源编译成字节码,那么为什么Dalvik不能运行某些类型的Java代码?
因为javac字节码输出是交叉编译的。交叉编译器(dx)处理非常特殊的javac输出,这意味着虽然它可以与经典的javac (您可以从java.sun.com获得的东西)和OpenJDK for Java1.5和1.6一起工作,但它不会与替代编译器(例如GCJ)一起工作,而且至少不会使用任何来自Java7的新字节码。
没有人能够解释什么是Dalvik固有的,使得无法从像Google或Apache这样的项目运行Java代码
就我个人而言,我从未使用过Google,尽管Roboguice在Android上工作。在回答您的问题之前,我从未听说过Apache,当我发现它不是Perl的Java端口时,我感到很困惑。:-)
任何运行时JVM字节码生成的工具都不能在Android上工作,仅仅因为交叉编译器只能在编译时使用,而不是运行时。另外,我不熟悉运行时JVM字节码生成工具使用的技术,以及它们如何让JVM执行字节码,因此我不知道Android中是否存在等效的钩子,以便让Dalvik运行任意块Dalvik字节码。
但是,由于您拒绝具体说明“来自Google Guice或Apache Camel等项目的Java代码”,您有问题,而且由于我对这些项目不太熟悉,因此很难对此作进一步的评论。
发布于 2015-01-13 04:33:07
这幅来自Android官方文档的图片展示了Android的构建过程,它将有助于理解java字节码和dalvik可执行文件之间的区别。

这里我举一个例子来说明其中的一些不同之处。
Hello.java
import java.io.*;
public class Hello {
public static void main(String[] args) {
System.out.println("hello world!!!!");
}
}使用javac将Hello.java编译为java字节码Hello.class
$ javac Hello.java然后使用android中的dx工具将java字节码Hello.class转换为Hello.dex。
$ $ANDROID_SDK_ROOT/build-tools/21.1.2/dx --dex --output=Hello.dex Hello.class然后,使用adb将Hello.class和Hello.dex放到Android设备或模拟器中。
$ adb push Hello.class /data/local/tmp/
$ adb push Hello.dex /data/local/tmp/使用adb shell进入Android设备的shell环境。然后使用命令/system/bin/dalvikvm执行我们刚刚创建的Hello.class和Hello.dex简单的java程序。
$ dalvikvm -Djava.class.path=./Hello.class Hello
java.lang.NoClassDefFoundError: Hello
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: Didn't find class "Hello" on path: ./Hello.class
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:65)
at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
... 1 mor
$ dalvikvm -Djava.class.path=./Hello.dex Hello
hello world!!!!在上面的示例中,当我们使用java字节码Hello.class,dalvikvm抱怨错误时,如果我们将类更改为dalvik可执行Hello.dex,它将正常运行。
https://stackoverflow.com/questions/11374477
复制相似问题