Android: javac vs Dalvik
Mi comprensión es que a Google no le gustaba la política de licencias de Oracle para usar el JRE en Java ME, así que lo reescribió usando su propia especificación JVM que imita al JRE pero se comporta un poco diferente, especialmente cuando se trata de hacer las cosas más eficientes y más seguro.
Por lo tanto, si mi comprensión es correcta, significa que cuando javac
se ejecuta en algún código fuente de Java y compilado en byetcode "binario", una JVM compatible interpretará que bytecode diferente a Dalvik (en algunos casos). Esta es la diferencia inherente entre Dalvik y otras JVM (compatibles).
- Deshabilitar el botón Inicio en la aplicación de pantalla de inicio?
- Cómo obtener la altura en píxeles de LinearLayout con layout_weight
- Android Wear: ¿Hay alguna razón para utilizar un objeto Time en lugar de un objeto Calendar?
- Análisis de un sitio web con Jsoup que se carga dinámicamente a medida que el usuario se desplaza
- Android - ¿Cómo obtener un contacto del registro de llamadas?
Si algo que he dicho hasta ahora es incorrecto, por favor comience por corregirme!
Ahora, si Android viene con su propio compilador (lo que podría), y compilado fuente de Java de una manera diferente (compatible con Dalvik) que javac
, entonces podría entender cómo algún código (no compilado con el SDK de Android) no se ejecuta en Un dispositivo 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
Sin embargo, parece que utiliza javac
para compilar aplicaciones de Android!?!? Así que parece que tenemos esto:
MySource.java --> javac --> MySource.class (JRE-compliant) --> JVM --> running Java app MySource.java --> javac --> MySource.class (JRE-compliant) --> Dalvik JVM --> running Android app (???)
Si javac
se utiliza para compilar todas las fuentes en bytecode, entonces ¿por qué es que Dalvik no puede ejecutar algunos tipos de código Java?
Hice una pregunta muy similar ayer y aunque técnicamente se respondió (después de volver a leer mi pregunta veo que simplemente no era lo suficientemente específico) nadie fue capaz de explicar lo que es inherente a Dalvik que hace que sea imposible ejecutar código Java Desde proyectos como Google Guice o Apache Camel. Me dijeron que para conseguir que Camel se ejecutara en Dalvik, que tendría que obtener la fuente de Camel y luego tendría que ser "construido con el SDK de Android", pero no pude obtener claridad sobre lo que eso significaba o implicaba .
Con Camel, por ejemplo, tienes esto (simplificado):
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 !!! (???)
Claramente, algo está sucediendo dentro de la JVM de Dalvik que le impide ejecutar ciertos tipos de código Java. Estoy tratando de entender qué tipos de código Java no se ejecutará cuando "alimentado" en la JVM de Dalvik.
Editar: En antes ", pero Camel 3.0 se ejecutará en Android! " Yo sé – no mi pregunta!
- Android Studio No hay opción "Importar muestra" en el menú Archivo
- getBeaconParsers (). add throws java.lang.UnsupportedOperationException
- JSON Serialización desde URL siempre devuelve NULL
- Android: Obtener Emoji desde EmojiconEditText
- Eliminar archivo de base de datos de la carpeta de activos
- TabWidget parpadea cuando el teclado oculta android
- Cómo implementar un FileObserver desde un servicio de Android
- ActivityCompat.requestPermissions que no muestran el cuadro de diálogo
I'm trying to understand what types of Java code will not run when "fed" into the Dalvik JVM.
La JVM de Dalvik difiere de otras JVMs en los siguientes aspectos:
-
Utiliza formato DEX especial para almacenar binarios de aplicaciones en comparación con los formatos JAR y Pack200 utilizados por las máquinas virtuales Java estándar. Google afirma que los resultados de DEX en binarios más pequeños que JAR. Creo que podrían usar Pack200 con el mismo éxito, pero decidieron seguir su propio camino en este aspecto
-
La JVM de Dalvik fue optimizada para ejecutar simultáneamente varios procesos JVM
-
Dalvik JVM utiliza la arquitectura basada en registros vs. arquitectura basada en pilas de otras JVMs con la intención de acelerar la ejecución y reducir los tamaños binarios
-
Utiliza su propio juego de instrucciones (no un bytecode estándar de JVM)
-
Uno puede ejecutar (si es necesario) varias aplicaciones independientes de Android dentro de un único proceso JVM
-
La ejecución de aplicaciones puede abarcar varios procesos de JVM de Dalvik "naturalmente". Para apoyar esto agrega:
-
Mecanismo de serialización de objetos especiales basado en clases Parcel y Parcelable. Funcionalmente cumple el mismo propósito que el estándar Java Serializable, pero resulta en una huella de datos más pequeña y es potencialmente más indulgente con las diferencias en las versiones de las clases
-
Forma especial de Android para ejecutar llamadas interproceso (IPC) basadas en el lenguaje de definición de interfaz de Android (AIDL)
-
-
Hasta que Android 2.2 Dalvik JVM no admitía la compilación JIT, lo que perjudicaba el rendimiento de las aplicaciones de Android. Añadirlo en 2.2 mejora notablemente la velocidad de ejecución de las aplicaciones que se utilizan con frecuencia
Si algo que he dicho hasta ahora es incorrecto, por favor comience por corregirme!
Ummm, bueno …
-
La VM Dalvik tiene ventajas técnicas sobre la VM Java para entornos móviles, sobre todo el uso agresivo del uso compartido de memoria de copia en escritura, por lo que toda la VM y la biblioteca de clases estándar se comparten entre todos los procesos de la aplicación Android SDK, Huella de la memoria. Vea la respuesta de user370305 (publicada mientras estaba envolviendo esto) para más.
-
El bytecode de
javac
es compilado en bytecode Dalvik como parte del proceso de construcción de aplicaciones de Android. La VM de Java no puede ejecutar el bytecode de Dalvik más de lo que puede ejecutar la salida de/dev/random
; De forma similar, la VM Dalvik no puede ejecutar bytecode Java.
Aquí hay una entrada de mi blog de hace dos años que entra en puntos adicionales.
Si javac se utiliza para compilar todas las fuentes en bytecode, entonces ¿por qué es que Dalvik no puede ejecutar algunos tipos de código Java?
Debido a que la salida de bytecode javac
está compuesta de forma cruzada. El compilador cruzado ( dx
) maneja un sabor muy específico de la salida de javac
, lo que significa que mientras trabaja con el clásico javac
(lo que habrías conseguido de java.sun.com) y OpenJDK para Java 1.5 y 1.6, no funcionará Con compiladores alternativos (por ejemplo, GCJ) y, como mínimo, no funcionará con ningún bytecode nuevo de Java 7.
Nadie fue capaz de explicar lo que es inherente a Dalvik que hace que sea imposible ejecutar código Java de proyectos como Google Guice o Apache Camel
Personalmente, nunca he utilizado Google Guice, aunque Roboguice funciona en Android. Nunca había oído hablar de Apache Camel antes de su pregunta y estoy bastante confundido para encontrar que no es un puerto Java de Perl. Todos los derechos reservados
Cualquier herramienta que ejecute generación de bytecode JVM no funcionará en Android, simplemente porque el compilador cruzado sólo está disponible en tiempo de compilación, no en tiempo de ejecución. Además, no estoy familiarizado con las técnicas utilizadas por las herramientas de generación de bytecode JVM de ejecución y cómo obtienen la JVM para ejecutar ese bytecode y, por lo tanto, no sé si existen ganchos equivalentes en Android para que Dalvik ejecute bloques arbitrarios de bytecode Dalvik.
Sin embargo, ya que no quiso especificar exactamente qué "código Java de proyectos como Google Guice o Apache Camel" está teniendo problemas, y como no estoy muy familiarizado con esos proyectos, es difícil comentar más.
Esta imagen de Android documento oficial ilustran el proceso de construcción de Android APK, que ayudará a entender la diferencia entre java bytecode y dalvik ejecutable.
Aquí les doy un ejemplo para demostrar algunas de las diferencias.
Hola jajaja
import java.io.*; public class Hello { public static void main(String[] args) { System.out.println("hello world!!!!"); } }
Utilizar javac
para compilar Hello.java
a java bytecode Hello.class
$ javac Hello.java
A continuación, utilice la herramienta dx
de android sdk convertir java bytecode Hello.class
a Hello.dex
$ $ANDROID_SDK_ROOT/build-tools/21.1.2/dx --dex --output=Hello.dex Hello.class
Después de eso, use adb
para poner Hello.class
y Hello.dex
en un dispositivo o emulador Android.
$ adb push Hello.class /data/local/tmp/ $ adb push Hello.dex /data/local/tmp/
adb shell
para ingresar al entorno de shell del dispositivo Android. A continuación, utilice el comando /system/bin/dalvikvm
para ejecutar el programa java simple que acabamos de crear Hello.class
y 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!!!!
En el ejemplo anterior, cuando usamos el bytecode de Java Hello.class
, dalvikvm
error de queja, si cambiamos la clase a dalvik ejecutable Hello.dex
, se ejecutaría correctamente.
- La navegación en modo inmersivo se vuelve pegajosa después de presionar el volumen o minimizarla
- Visualización de un archivo MS Word en la vista (diga TextView) en Android