Android: javac vs Dalvik
Ma compréhension est que Google n'a pas aimé la Politique de licence D'Oracle pour utiliser le JRE en Java moi donc il a juste réécrit il utilise sa propre spécification JVM qui imite {[9] } le JRE mais se comporte un peu différemment, surtout quand il s'agit pour rendre les choses plus efficaces et plus sûres.
Donc, si ma compréhension est correcte, cela signifie que lorsque javac
est exécuté sur du code source Java et compilé dans " binary"
byetcode, une JVM conforme interprétera ce bytecode différent de Dalvik sera (dans certains cas). C'est inhérente à l'
différence entre Dalvik et d'autres JVM (conformes).
Si quelque chose que j'ai dit jusqu'à présent est incorrect, veuillez commencer par me corriger!
Maintenant, si Android est venu avec son propre compilateur (ce qu'il pourrait), et compilé la source Java dans un autre (conforme Dalvik)
de manière que javac
, alors je pourrais comprendre comment un code (non compilé avec le SDK Android) ne fonctionnerait pas sur un
Appareil 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
Cependant, il on dirait que vous utilisez javac
pour compiler des applications Android!?!? Il semble donc que nous ayons ceci:
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
est utilisé pour compiler toutes les sources en bytecode, alors pourquoi Dalvik ne peut-il pas exécuter certains types
de code Java?
J'ai posé une question très similaire hier et bien qu'elle ait été techniquement répondue (après avoir relu ma question Je vois que je n'étais tout simplement pas assez précis) personne n'a pu expliquer ce qui est inhérent à Dalvik que rend impossible l'exécution du code Java à partir de des projets comme Google Guice ou Apache Camel. On m'a dit que pour que Camel fonctionne sur Dalvik, je devrais obtenir la source de Camel et ensuite il devrait être "construit avec le SDK Android", mais je ne pouvais pas obtenir de clarté sur ce que cela signifiait ou impliquait.
Avec Camel, par exemple, vous avez ceci (simplifié):
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 !!! (???)
Il est clair que quelque chose se passe à L'intérieur de la JVM Dalvik qui l'empêche d'exécuter certains types de code Java. j'essaie de comprendre quels types de Le code Java ne s'exécutera pas lorsqu'il sera "alimenté" dans la JVM Dalvik.
Edit: En avant ", mais Chameau 3.0 fonctionnera sur Android! " je sais-pas ma question!
4 réponses
I'm trying to understand what types of Java code will not run when "fed" into the Dalvik JVM.
Dalvik JVM diffère des autres JVM dans les aspects suivants:
Il utilise le format Dex spécial pour stocker les applications binaires vs. JAR et les formats Pack200 utilisés par les machines virtuelles Java standard. Google affirme que DEX entraîne des binaires plus petits que JAR. Je pense qu'ils pourrait utiliser Pack200 avec le même succès, mais ils ont décidé d'aller leur dans cet aspect
-
Dalvik JVM a été optimisé pour l'exécution de plusieurs JVM processus en même temps
-
La JVM Dalvik utilise une architecture basée sur les registres par rapport à une pile architecture d'autres JVM avec l'intention d'accélérer l'exécution et pour réduire les tailles binaires
-
Il utilise son propre jeu d'instructions (pas un bytecode JVM standard)
-
On peut exécuter (si nécessaire) plusieurs applications Android indépendantes dans un seul processus JVM
-
L'exécution de L'Application peut s'étendre sur plusieurs processus JVM Dalvik "naturellement". De l'appui de ce qu'il ajoute:
-
Mécanisme de sérialisation D'objet spécial basé sur Parcel et Parcelable classe. Fonctionnellement il sert le même but que Java standard Sérialisable, mais entraîne une empreinte de données plus petite et est potentiellement plus indulgente vis-à-vis des différences dans les versions des classes
-
Spécial Android façon d'exécuter inter processus appels (IPC) basé sur Android Interface définition langue (AIDL)
-
Jusqu'À Android 2.2 Dalvik JVM n'a pas pris en charge la compilation JIT qui impacté négativement les performances des applications Android. Ajouter en 2.2 améliore nettement la vitesse d'exécution pour les applications souvent utilisées
Si quelque chose que j'ai dit jusqu'à présent est incorrect, veuillez commencer par me corriger!
Ummm, Eh bien...
La VM Dalvik présente des avantages techniques par rapport à la VM Java pour les environnements mobiles, notamment l'utilisation agressive du partage de mémoire copie sur écriture, de sorte que la VM entière et la bibliothèque de classes standard sont partagées entre tous les processus D'Applications SDK Android, réduisant ainsi l'empreinte mémoire nette par processus. Voir la réponse de user370305 (posté pendant que j'enveloppais cela) pour plus.
Le bytecode de
javac
est compilé en bytecode Dalvik dans le cadre du processus de génération D'applications Android. La VM Java ne peut pas exécuter le bytecode Dalvik plus qu'elle ne peut exécuter la sortie de/dev/random
; de même, la VM Dalvik ne peut pas exécuter le bytecode Java.
Voici un billet de blog à moi d'il y a environ deux ans qui va dans des points supplémentaires.
Si javac est utilisé pour compiler toutes les sources en bytecode, alors pourquoi est-ce que Dalvik ne peut pas exécuter certains types de code Java?
Parce que la sortie du bytecode javac
est compilée de manière croisée. Le compilateur croisé (dx
) gère une saveur très spécifique de la sortie javac
, ce qui signifie que bien qu'il fonctionne avec le classique javac
(ce que vous auriez obtenu de java.sun.com) et OpenJDK pour Java 1.5 et 1.6, il ne fonctionnera pas avec des compilateurs alternatifs (par exemple, GCJ) et, au minimum, ne fonctionnera pas avec de nouveaux bytecodes de Java 7.
Personne n'a pu expliquer ce qui est inhérent à Dalvik, c'est qu'il est impossible d'exécuter du code Java à partir de projets comme Google Guice ou Apache Camel
Personnellement, je n'ai jamais utilisé Google Guice, bien que Roboguice Fonctionne sur Android. Je n'avais jamais entendu parler D'Apache Camel avant votre question et je suis plutôt confus de constater que ce n'est pas un port Java de Perl. :-)
Tous les outils qui font la génération de bytecode JVM runtime ne fonctionneront pas sur Android, simplement parce que le compilateur croisé est seulement disponible au moment de la compilation, pas au moment de l'exécution. En outre, Je ne suis pas familier avec les techniques utilisées par les outils de génération de bytecode JVM runtime et comment ils obtiennent la JVM pour exécuter ce bytecode,et donc je ne sais pas si des crochets équivalents existent dans Android pour que Dalvik exécute des morceaux arbitraires de bytecode Dalvik.
Cependant, puisque vous avez refusé de spécifier exactement quel "code Java de projets comme Google Guice ou Apache Camel" vous rencontrez des problèmes, et puisque je ne suis pas intimement familier avec ces projets, il est difficile de commenter davantage.
Cette image du document officiel Android illustre le processus de construction D'Android APK, il aidera à comprendre la différence entre java bytecode et exécutable dalvik.
Ici, je donne un exemple pour démontrer certaines des différences.
Bonjour.java
import java.io.*;
public class Hello {
public static void main(String[] args) {
System.out.println("hello world!!!!");
}
}
Utiliser javac
pour compiler Hello.java
pour le bytecode java Hello.class
$ javac Hello.java
Ensuite, utilisez dx
outil de Android sdk convertir java bytecode Hello.class
à Hello.dex
$ $ANDROID_SDK_ROOT/build-tools/21.1.2/dx --dex --output=Hello.dex Hello.class
Après cela, utilisez adb
pour mettre Hello.class
et Hello.dex
sur un appareil ou un émulateur Android.
$ adb push Hello.class /data/local/tmp/
$ adb push Hello.dex /data/local/tmp/
Utilisez adb shell
pour entrer dans l'environnement shell de L'appareil Android. Puis utiliser la commande /system/bin/dalvikvm
pour exécuter le programme java simple que nous venons de créer Hello.class
et 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!!!!
Dans l'exemple ci-dessus, lorsque nous utilisons le bytecode java Hello.class
, dalvikvm
erreur de plainte, si nous changions la classe en exécutable dalvik Hello.dex
, elle fonctionnerait correctement.
@ alijandro, vous avez très bien expliqué comment dalvikvm peut exécuter pnly .dex
code octet et non .class
code octet.
Pour le processus de construction de L'Image Android APK que vous avez joint quelles sont les conventions utilisées pour le codage couleur et les chiffres? Pouvez vous s'il vous plaît joindre une référence ?