IAm*_*aja 25 java android javac dalvik
我的理解是,Google不喜欢Oracle在Java ME中使用JRE的许可政策,所以它只是使用自己的JVM规范重写它,模仿 JRE但行为有点不同,特别是在提高效率和更安全.
因此,如果我的理解是正确的,那意味着当javac
在某些Java源代码上运行并编译成"二进制"byetcode时,兼容的JVM将解释与Dalvik不同的字节码(在某些情况下).这是Dalvik与其他(兼容)JVM之间的固有差异.
如果我到目前为止所说的任何内容都不正确,请先纠正我!
现在,如果Android带有自己的编译器(它可能),并以不同的(Dalvik兼容)方式编译Java源代码javac
,那么我可以理解一些代码(不是用Android SDK编译)不会运行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
Run Code Online (Sandbox Code Playgroud)
但是,它看起来像你javac
用来编译Android应用程序!?!?所以看起来我们有这个:
MySource.java --> javac --> MySource.class (JRE-compliant) --> JVM --> running Java app
MySource.java --> javac --> MySource.class (JRE-compliant) --> Dalvik JVM --> running Android app (???)
Run Code Online (Sandbox Code Playgroud)
如果javac
用于将所有源代码编译为字节码,那为什么Dalvik无法运行某些类型的Java代码呢?
昨天我问了一个非常相似的问题,虽然它在技术上得到了解答(在重新阅读我的问题之后,我发现我根本不够具体)没有人能够解释Dalvik固有的是什么使得无法运行Java代码来自Google Guice或Apache Camel等项目.有人告诉我,为了让Camel在Dalvik上运行,我必须得到Camel的源代码然后它必须"使用Android SDK构建",但我无法明确这意味着什么或暗示.
以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 !!! (???)
Run Code Online (Sandbox Code Playgroud)
显然,Dalvik JVM内部正在发生一些事情,阻止它运行某些类型的Java代码. 我试图了解当"馈入"Dalvik JVM时,哪些类型的Java代码不会运行.
编辑:之前" 但Camel 3.0将在Android上运行! "我知道 - 不是我的问题!
use*_*305 28
I'm trying to understand what types of Java code will not run when "fed" into the Dalvik JVM.
Run Code Online (Sandbox Code Playgroud)
Dalvik JVM在以下方面与其他JVM不同:
它使用特殊的DEX格式来存储应用程序二进制文件与标准Java虚拟机使用的JAR和Pack200格式.谷歌声称DEX导致比JAR更小的二进制文件.我认为他们可以使用Pack200取得同样的成功,但他们决定在这方面走自己的路
Dalvik JVM针对同时运行多个JVM进程进行了优化
Dalvik JVM使用基于寄存器的体系结构与其他JVM的基于堆栈的体系结构,旨在加快执行速度并减少二进制文件大小
它使用自己的指令集(不是标准的JVM字节码)
可以在单个JVM进程中运行(如果需要)几个独立的Android应用程序
应用程序执行可以"自然地"跨越多个Dalvik JVM进程.为了支持这一点,它增加:
基于Parcel和Parcelable类的特殊对象序列化机制.从功能上讲,它与标准Java Serializable具有相同的用途,但可以减少数据占用空间,并且可能对类版本的差异更加宽容
基于Android界面定义语言(AIDL)执行进程间调用(IPC)的特殊Android方式
直到Android 2.2 Dalvik JVM不支持JIT编译,这对Android应用程序性能产生了不利影响.在2.2中添加它可以显着提高常用应用程序的执行速度
Com*_*are 24
如果我到目前为止所说的任何内容都不正确,请先纠正我!
嗯,好吧......
Dalvik VM相对于移动环境的Java VM具有技术优势,最显着的是积极使用写时复制内存共享,因此整个VM和标准类库在所有Android SDK应用程序进程之间共享,从而减少了每个进程的净流程内存占用.请参阅user370305的答案(在我收尾时发布)以获取更多信息.
javac
作为Android应用程序构建过程的一部分,字节码被交叉编译为Dalvik字节码.Java VM不能执行Dalvik字节码,它可以执行输出/dev/random
; 同样,Dalvik VM无法执行Java字节码.
如果使用javac将所有源代码编译成字节码,那为什么Dalvik无法运行某些类型的Java代码?
因为javac
字节码输出是交叉编译的.cross-compiler(dx
)处理一种非常特殊的javac
输出风格,这意味着虽然它适用于经典javac
(你可以从java.sun.com获得)和OpenJDK for Java 1.5和1.6,但它不能与替代编译器一起使用(例如,GCJ),并且至少不适用于Java 7中的任何新字节码.
没有人能够解释Dalvik所固有的是什么使得无法从Google Guice或Apache Camel等项目运行Java代码
就个人而言,我从未使用过Google Guice,尽管Roboguice适用于Android.在你的问题之前我从来没有听说过Apache Camel,我很困惑地发现它不是Perl的Java端口.:-)
任何执行运行时JVM字节码生成的工具都不能在Android上运行,因为交叉编译器仅在编译时可用,而不是在运行时.此外,我不熟悉运行时JVM字节码生成工具使用的技术以及它们如何让JVM执行该字节码,因此我不知道Android中是否存在等效的钩子以使Dalvik运行任意的Dalvik字节码块.
但是,由于您拒绝准确指出"Google Guice或Apache Camel等项目中的Java代码"您遇到了什么问题,并且由于我对这些项目并不熟悉,因此很难进一步评论.
ali*_*dro 11
这张来自Android官方文档的图片说明了Android APK的构建过程,它将有助于理解java字节码和dalvik可执行文件之间的区别.
在这里,我举一个例子来说明一些不同之处.
Hello.java
import java.io.*;
public class Hello {
public static void main(String[] args) {
System.out.println("hello world!!!!");
}
}
Run Code Online (Sandbox Code Playgroud)
用于javac
编译Hello.java
为java字节码Hello.class
$ javac Hello.java
Run Code Online (Sandbox Code Playgroud)
然后使用dx
android sdk工具将java字节码转换Hello.class
为Hello.dex
$ $ANDROID_SDK_ROOT/build-tools/21.1.2/dx --dex --output=Hello.dex Hello.class
Run Code Online (Sandbox Code Playgroud)
在此之后,使用adb
投入Hello.class
和Hello.dex
对Android设备或模拟器.
$ adb push Hello.class /data/local/tmp/
$ adb push Hello.dex /data/local/tmp/
Run Code Online (Sandbox Code Playgroud)
用于adb shell
进入Android设备的shell环境.然后使用命令/system/bin/dalvikvm
来执行我们刚创建的简单的Java程序Hello.class
和Hello.dex
$ 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!!!!
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,当我们使用java字节码时Hello.class
,dalvikvm
抱怨错误,如果我们将类更改为dalvik可执行文件Hello.dex
,它将正常运行.