Android: javac vs Dalvik


Насколько я понимаю, Google не понравилась политика лицензирования Oracle для использования JRE в Java ME, поэтому он просто переписал он использует свою собственную спецификацию JVM, которая имитирует JRE, но ведет себя немного по-другому, особенно когда он приходит к тому, чтобы сделать вещи более эффективными и более безопасными.

Итак, если мое понимание верно, это означает, что когда javac выполняется на некотором исходном коде Java и компилируется в " двоичный код" byetcode, совместимый JVM интерпретирует этот байт-код отличается от Дальвика (в некоторых случаях). Это неотъемлемое свойство разница между Dalvik и другими (совместимыми) JVMs.

Если что-то из того, что я сказал до сих пор, неверно, пожалуйста, начните с исправления меня!

Теперь, если 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 используется для компиляции всех источников в байт-код, то почему Dalvik не может запускать некоторые типы из кода Java?

Вчера я задал очень похожий вопрос, и хотя технически на него был дан ответ (после перечитывания моего вопроса Я вижу, что я был просто недостаточно конкретен) никто не смог объяснить, что это такое, что присуще Далвику, что делает невозможным выполнение кода Java из такие проекты, как Google Guice или Apache Camel. Мне сказали, что для того, чтобы заставить Camel работать на Dalvik, мне нужно будет получить Camel's source, а затем он должен быть "построен с помощью Android SDK", но я не мог понять, что это означает или подразумевается.

С верблюдом, например, у вас есть это (упрощенно):

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.

Edit: In before " но Camel 3.0 будет работать на Android! " я знаю - не мой вопрос!

4 25

4 ответа:

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. Гугл утверждает, что DEX приводит к меньшим двоичным файлам, чем JAR. Я думаю, что они могли бы использовать Pack200 с тем же успехом, но они решили пойти своим свой путь в этом аспекте

  • Dalvik JVM был оптимизирован для работы с несколькими JVM процессы одновременно

  • Dalvik JVM использует регистровую архитектуру в сравнении со стековой архитектура других СПМ с намерением ускорить выполнение и чтобы уменьшить двоичные размеры

  • Он использует свой собственный набор инструкций (не стандартный байт-код JVM)

  • Можно запустить (при необходимости) несколько независимых приложений для Android в рамках одного процесса JVM

  • Выполнение приложения может охватывать несколько процессов Dalvik JVM "естественно". К поддержка этого добавляет:

    • Специальный механизм сериализации объектов на основе Parcel и Parcelable занятия. Функционально он служит той же цели, что и стандартный Java Сериализуемый, но приводит к меньшему объему данных и потенциально более снисходителен к различиям в версиях классов

    • Специальный Android-Способ выполнения межпроцессных вызовов (IPC) на основе Язык определения интерфейса Android (AIDL)

  • До Android 2.2 Dalvik JVM не поддерживает компиляцию JIT, которая отрицательно сказалось на производительности приложений Android. Добавление его в 2.2 заметно повышает скорость выполнения часто используемых приложений

Если что-то из того, что я сказал до сих пор, неверно, пожалуйста, начните с исправления меня!

Ммм, ну...

  • Виртуальная машина Dalvik имеет технические преимущества перед виртуальной машиной Java для мобильных сред, в частности агрессивное использование совместного использования памяти при копировании на запись, поэтому вся виртуальная машина и стандартная библиотека классов совместно используются всеми процессами приложения Android SDK, что сокращает объем памяти, занимаемой каждым процессом. Смотрите ответ user370305 (опубликованный, когда я заканчивал это) для больше.

  • Байт-код из javac кросс-компилируется в байт-код Dalvik как часть процесса сборки приложения Android. Java VM не может выполнить байт-код Dalvik больше, чем он может выполнить вывод /dev/random; аналогично, Dalvik VM не может выполнить байт-код Java.

Вот мой пост в блоге примерно двухлетней давности, который входит в дополнительные пункты.

Если javac используется для компиляции всех источников в байт-код, то почему дело в том, что Dalvik не может запускать некоторые типы 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, просто потому, что кросс-компилятор только доступно во время компиляции, а не во время выполнения. Кроме того, я не знаком с методами, используемыми средствами генерации байт-кода JVM во время выполнения, и как они заставляют JVM выполнять этот байт-код, и поэтому я не знаю, существуют ли эквивалентные хуки в Android, чтобы заставить Dalvik запускать произвольные куски байт-кода Dalvik.

Однако, поскольку вы отказались точно указать, с каким "Java-кодом из таких проектов, как Google Guice или Apache Camel", у вас возникли проблемы, и поскольку я не очень хорошо знаком с эти проекты трудно комментировать дальше.

Эта картинка из официального документа Android иллюстрирует процесс сборки Android APK, она поможет понять разницу между байт-кодом java и исполняемым файлом dalvik. Введите описание изображения здесь

Здесь я привожу пример, чтобы продемонстрировать некоторые различия.

Здравствуйте.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 преобразовать байт-код 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. Затем используйте команду /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!!!!

В примере выше, когда мы используем байт-код javaHello.class, dalvikvm ошибка жалобы, если мы изменим класс на dalvik executable Hello.dex, он будет работать правильно.

@alijandro, вы очень хорошо объяснили, как dalvikvm может выполнять байт-код .dex, а не байт-код .class. Для процесса сборки Android APK picture вы прикрепили какие соглашения используются для цветового кодирования и цифр? Не могли бы вы приложить справку ?