Android: javac vs Dalvik

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

Итак, если мое понимание правильное, это означает, что когда javac запускается на каком-то исходном коде Java и скомпилирован в «двоичный» байтовый код, совместимая 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.

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

 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 и Parcelable. Функционально он выполняет ту же задачу, что и стандартный Java Serializable, но приводит к уменьшению объема данных и потенциально более снисходителен к различиям в версиях классов

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

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

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

Уммм, ну …

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

  • Байт-код из 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», с которыми вы сталкиваетесь, и, поскольку я не знаком с этими проектами, сложно комментировать его дальше.

Это изображение из официального документа Android иллюстрирует процесс сборки Android APK, это поможет понять разницу между 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 

Затем используйте инструмент 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-байт-код Hello.class , dalvikvm error error, если мы изменили класс на dalvik исполняемый Hello.dex , он будет работать правильно.

Intereting Posts
Исправлено предупреждение о сбое Android-плеера: статус 0x1 Как отключить прослушиватель onclick при просмотре представления в андроиде? String.equals () всегда возвращает true Android OkHttp addPathSegment заменяет косые черты «Плагин org.eclipse.jdt.ui не смог загрузить класс org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart.» В adt (v22.6.2) Как узнать, отклонен ли диалог в Android? Как развернуть текст для обтекания изображения Чтобы использовать HW-декодер в android через libstagefright, что установить для kKeyAVCC в метаданных для декодирования базовой базы вместо воспроизведения MP4? Сбой приложений для Android для некоторых пользователей при применении преобразования с Picasso Не удалось создать службу java.lang.NullPointerException Gitignore misc.xml и * .iml с Android Studio 0.8.9 Лучшая практика для повторных сетевых задач? Android: в чем разница между разрешением и плотностью? Может ли DataBinding вмешиваться в локализацию Activity? Удаление регистрации из производственного кода в Android?