Android: javac vs Dalvik
Я понимаю, что Google не любил политику лицензирования Oracle для использования JRE в Java ME, поэтому он просто переписал
он использует свою собственную спецификацию JVM, которая имитирует JRE, но ведет себя немного по-другому, особенно когда она приходит
чтобы сделать вещи более эффективными и более безопасными.
Итак, если мое понимание правильное, это означает, что когда javac
запускается на каком-то исходном коде Java и скомпилируется в "двоичный"
byetcode, совместимая JVM будет интерпретировать, что байт-код, отличный от Dalvik, будет (в некоторых случаях). Это присущее
разница между Dalvik и другими (совместимыми) JVM.
Если что-то, что я сказал до сих пор, неверно, начните с исправления!
Теперь, если Android пришел со своим собственным компилятором (каким он мог) и скомпилировал исходный Java-источник в другом (Dalvik-совместимый)
чем 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
Однако, похоже, вы используете 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 (???)
Если javac
используется для компиляции всех источников в байт-код, то почему Далвик не может запускать некоторые типы
кода 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 !!! (???)
Очевидно, что что-то происходит внутри JVM Dalvik, что мешает ему запускать определенные типы Java-кода.
Я пытаюсь понять, какие типы Java-кода не будут выполняться при "подаче" в JVM Dalvik.
Изменить: В начале, но Camel 3.0 будет работать на Android! " Я знаю - не мой вопрос!
Ответы
Ответ 1
I'm trying to understand what types of Java code will not run when "fed" into the Dalvik JVM.
Dalvik JVM отличается от других JVM следующими аспектами:
-
Он использует специальный формат DEX для хранения двоичных файлов приложений и JAR
и Pack200, используемые стандартными виртуальными машинами Java. Google
утверждает, что DEX приводит к меньшим двоичным файлам, чем JAR. Я думаю, что они
могли использовать Pack200 с таким же успехом, но решили
собственный путь в этом аспекте
-
Dalvik JVM оптимизирован для запуска нескольких процессов JVM
одновременно
-
Dalvik JVM использует архитектуру на основе регистров и стек
архитектуры других JVM с намерением ускорить выполнение и
уменьшить двоичные размеры
-
Он использует свой собственный набор инструкций (а не стандартный байт-код JVM)
-
Можно запустить (при необходимости) несколько независимых приложений для Android
в рамках одного процесса JVM
-
Выполнение приложения может охватывать несколько процессов JVM Dalvik
"Естественно". Чтобы поддержать это,
добавляет:
-
Механизм сериализации специальных объектов на основе Parcel and Parcelable
классы. Функционально он служит той же цели, что и стандартная Java
Сериализуемый, но приводит к уменьшению объема данных и потенциально более снисходителен к различиям в версиях классов.
-
Специальный способ Android для выполнения межпроцессных вызовов (IPC) на основе
Язык определения интерфейса Android (AIDL)
-
Пока Android 2.2 Dalvik JVM не поддерживает компиляцию JIT, которая
неблагоприятно сказывается на производительности приложений Android. Добавление его в 2.2
улучшает заметно скорость выполнения для часто используемых приложений.
Ответ 2
Если что-то, что я сказал до сих пор, неверно, начните с исправления!
Уммм, ну...
-
У Dalvik VM есть технические преимущества по сравнению с Java VM для мобильных сред, в первую очередь агрессивное использование совместного использования памяти для копирования на запись, поэтому вся виртуальная машина и библиотека стандартных классов распределяются между всеми процессами приложений Android SDK, уменьшая объем загружаемой памяти для каждого процесса. См. User370305 answer (опубликовано, пока я обертывал это) для большего.
-
Байт-код из javac
кросс-компилируется в байт-код Dalvik как часть процесса сборки приложений Android. Java VM не может выполнить байт-код Dalvik больше, чем может выполнять вывод /dev/random
; аналогичным образом, Dalvik VM не может выполнять Java-байт-код.
Вот мое сообщение в блоге около двух лет назад, которое входит в дополнительные пункты.
Если javac используется для компиляции всех источников в байт-код, то почему Далвик не может запускать некоторые типы Java-кода?
Поскольку вывод javac
байт-кода скомпилирован. Кросс-компилятор (dx
) обрабатывает очень специфический вкус вывода javac
, что означает, что, хотя он работает с классическим javac
(то, что вы получили от java.sun.com) и OpenJDK для Java 1.5 и 1.6, он не будет работать с альтернативными компиляторами (например, GCJ) и, как минимум, не будет работать с любыми новыми байткодами из Java 7.
никто не смог объяснить, что присуще Dalvik, что делает невозможным запуск Java-кода из таких проектов, как Google Guice или Apache Camel
Лично я никогда не использовал Google Guice, хотя Roboguice работает на Android. Я никогда не слышал об Apache Camel до вашего вопроса и довольно смущен, обнаружив, что это не порт Java Perl.: -)
Любые инструменты, выполняющие генерацию байт-кода JVM во время выполнения, не будут работать на Android, просто потому, что кросс-компилятор доступен только во время компиляции, а не во время выполнения. Кроме того, я не знаком с методами, используемыми инструментами генерации байт-кода runtime JVM, и как они получают JVM для выполнения этого байт-кода, и поэтому я не знаю, существуют ли в Android эквивалентные крючки, чтобы Dalvik выполнял произвольные фрагменты байт-кода Dalvik.
Однако, поскольку вы отказались уточнить, что такое "Java-код от таких проектов, как Google Guice или Apache Camel", с которыми вы сталкиваетесь, и, поскольку я не знаком с этими проектами, сложно комментировать дальше.
Ответ 3
Это изображение официального документа Android иллюстрирует процесс сборки Android APK, это поможет понять разницу между java байт-кодом и исполняемым файлом dalvik.
![enter image description here]()
Здесь я приведу пример, чтобы продемонстрировать некоторые различия.
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
Затем используйте инструмент dx
из android sdk convert java bytecode 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-устройства. Затем используйте команду /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!!!!
В приведенном выше примере, когда мы используем ошибку java bytecode Hello.class
, dalvikvm
, если мы изменили класс на dalvik executable Hello.dex
, он будет работать правильно.