Подтвердить что ты не робот

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! " Я знаю - не мой вопрос!

4b9b3361

Ответ 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, он будет работать правильно.