189 votes

Fonctionnalités du langage Java 7 avec Android

Je me demandais si quelqu'un a déjà essayé en utilisant les nouvelles fonctionnalités du langage Java 7 avec Android ? Je sais que Android lit le bytecode que Java crache et le transforme à dex. Donc je suppose que ma question est peut il comprendre le bytecode Java 7 ?

166voto

KennyTM Points 232647

Une petite partie de Java 7 peut certainement être utilisé avec Android (note: je ne l'ai testé que sur 4.1).

Tout d'abord, vous ne pouviez pas utiliser Eclipse de l'ADT, car il est codé en dur que seul le compilateur Java 1.5 et 1.6 sont conformes. Vous pourriez recompiler ADT, mais je trouve qu'il y a pas de façon simple de le faire qu'en dehors de recompiler l'ensemble de l'Androïde ensemble.

Mais vous n'avez pas besoin d'utiliser Eclipse. Par exemple, Android Studio 0.3.2, IntelliJ IDEA de la CE et d'autres javac-fondé de l'Ide prend en charge la compilation d'Android et vous pouvez définir la conformité même jusqu'à Java 8 avec:

  • Fichier → Structure de Projet → Modules → (choisissez le module lors de la 2ème volet) → niveau de Langue → (choisir "7.0 - Diamants, des BRAS, des multi-prises, etc....")

Enabling Java 7 on IntelliJ

Cela ne vous permet de Java 7 fonctionnalités de la langue, et vous ne pouvez pas bénéficier de quoi que ce soit depuis un demi d'amélioration provient de la bibliothèque. Les fonctionnalités que vous pourriez utiliser sont ceux qui ne dépendent pas de la bibliothèque:

  • Diamant opérateur (<>)
  • Chaîne de commutateur
  • Plusieurs captures (catch (Exc1 | Exc2 e))
  • Le trait de soulignement dans nombre de littéraux (1_234_567)
  • Binaire littéraux (0b1110111)

Et ces caractéristiques ne peuvent pas être utilisés encore:

  • L' try-avec-les ressources de l'instruction, car il nécessite le non-existant interface "java.lang.AutoCloseable" (il peut être utilisé publiquement à 4.4+)
  • @SafeVarargs annotation - parce que "la java.lang.SafeVarargs" n'existe pas

... "encore" :) Il s'avère que, bien que Android bibliothèque de l'est de ciblage pour la 1.6, la source Android contient les interfaces de AutoCloseable traditionnels et les interfaces de Fermer ne hériter de AutoCloseable (SafeVarargs qui manque vraiment, tout de même). Nous avons pu confirmer son existence par la réflexion. Ils sont cachés tout simplement parce que la Javadoc a l' @hide balise, qui a causé la "android.jar" de ne pas l'inclure.

Il y a déjà existant question Comment puis-je construire le SDK Android cachés et interne de l'Api disponibles? sur comment obtenir ces méthodes en arrière. Vous avez juste besoin de remplacer l'existant "android.jar" référence de la Plate-forme actuelle avec notre personnalisés, alors que beaucoup de Java 7 Api sera disponible (la procédure est la même que dans Eclipse. De Vérifier La Structure Du Projet → Kits De Développement Logiciel.)

En plus de AutoCloseable, (seulement) à l'issue de Java 7 les fonctions de la bibliothèque sont aussi révélées:

  • Exception chaînage des constructeurs en ConcurrentModificationException, LinkageError et AssertionError
  • La statique .comparer() les méthodes de primitives: Boolean.comparer(), Byte.comparer(), Court.comparer(), de Caractère.comparer(), Entier.comparer(), Long.comparer().
  • Monnaie: .getAvailableCurrencies(), .getDisplayName() (mais sans .getNumericCode())
  • BitSet: .previousSetBit(), .previousClearBit(), .valueOf(), .toLongArray(), .toByteArray()
  • Collections: .emptyEnumeration(), .emptyIterator(), .emptyListIterator()
  • AutoCloseable
  • Throwable: .addSuppressed(), .getSuppressed(), et le 4-argument du constructeur
  • Caractère: .comparer(), .isSurrogate(), .getName(), .highSurrogate(), .lowSurrogate(), .isBmpCodePoint() (mais sans .isAlphabetic() et .isIdeographic())
  • Système: .lineSeparator() (sans-papiers?)
  • java.lang.de réfléchir.Modificateur: .classModifiers(), .constructorModifiers(), .fieldModifiers(), .interfaceModifiers(), .methodModifiers()
  • NetworkInterface: .getIndex(), .getByIndex()
  • InetSocketAddress: .getHostString()
  • InetAddress: .getLoopbackAddress()
  • Enregistreur: .getGlobal()
  • ConcurrentLinkedDeque
  • AbstractQueuedSynchronizer: .hasQueuedPredecessors()
  • DeflaterOutputStream: les 3 constructeurs avec "syncFlush".
  • Deflater: .NO_FLUSH, .SYNC_FLUSH, .FULL_FLUSH, .dégonfler() avec 4 arguments

C'est à peu près tout. En particulier, NIO 2.0 n'existe pas, et les Tableaux.asList est pas encore @SafeVarargs.

70voto

Shlublu Points 6199

EDIT: À l'époque, c'était écrit, la dernière version est Android 9 et Eclipse Indigo. Chose ont changé depuis.

  • Réponse pratique

Oui, j'ai essayé. Mais ce n'est pas un bon test de la compatibilité a été limitée au niveau 6 avec aucune façon (pas de moyen simple au moins) pour vraiment utiliser java 7:

  • J'ai d'abord installé un JDK7 sur une machine qui n'avait pas d'autre JDK installé Eclipse et Android ne sont pas installés, soit:

The 7 is the only installed on this machine

  • Puis j'ai installé une nouvelle marque Eclipse Indigo et vérifié qu'il était en fait en utilisant le JDK 7 (eh bien, comme c'est le seul et que c'est celui que j'ai choisi, j'aurais été surpris)

The 7 is the only used by this Eclipse

  • Puis j'ai installé la dernière version du SDK Android (EDIT: en Nid d'abeille, API13, au moment de ce post a été écrit). Il a trouvé mon JDK 7 et installé correctement. De même pour l'outil ADT.

  • Mais j'ai eu une surprise lorsque vous essayez de compiler et d'exécuter un Hello Word Android app. La compatibilité a été définie pour la version 6 de Java avec aucun moyen de le forcer à Java 7:

Compatibility is limited to Java 6

  • J'ai essayé avec un non-projet Android, Java, et j'ai eu l'explication. Le niveau de compatibilité semble être limité par Eclipse (voir le message au bas de l'image ci-dessous):

Eclipse limits itself to level 6 compatibility

J'ai donc dû Bonjour à tout le Monde de travail, et aussi d'autres applications, plus complexe et, à l'aide de SQLite, Listview, Sensor et Camera, mais cela prouve seulement que la compatibilité de la manipulation de Java 7 semble être bien fait et le travail avec Android.

Donc, quelqu'un a essayer avec la bonne vieille Fourmi, pour contourner l'Éclipse limitation vu ci-dessus?

  • Theroetical répondre

De toute façon, le SDK est conçu pour être utilisé avec Java 5 ou 6, comme expliqué ici.

Nous pouvons avoir quelque chose à travailler avec Java 7, mais il serait de travail "par accident". La construction de l'indice DEX peut fonctionner correctement ou non, et une fois que le DEX construit, il peut fonctionner ou pas. Cela parce que, à l'aide d'un non-qualifiés JDK donne des résultats imprévisibles par définition.

Même si quelqu'un a réussi à construit une application Android en vertu de la plaine de Java 7, ce n'est pas admissible à la JDK. Le même procédé appliqué à une autre application peut échouer, ou l'application qui en résulte peut avoir des bugs liés à l'utilisation du JDK. Pas recommandé.

Pour ceux qui sont impliqués sur les webapps de développement, ce exactement le même que le déploiement d'une application web construit sous Java 5 ou 6 dans un serveur d'application qualifié pour Java 4 seulement (disons Weblogic 8 par exemple). Cela peut fonctionner, mais ce n'est pas quelque chose qui peut être recommandé à d'autres fins que d'essayer.

38voto

Andi Points 783

Citation de dalvikvm.com:

dx, inclus dans le SDK Android, transforme les fichiers de Classe Java des classes Java compilé par un compilateur Java dans une autre classe de format de fichier (.dex format)

Cela signifie que le .java fichier source n'a pas d'importance, c'est seulement le .classe de bytecode.

Autant que je sache, seulement invokedynamic a été ajouté à la JVM du bytecode Java 7, le reste est compatible avec la version 6 de Java. Le langage Java lui-même n'utilise pas invokedynamic. D'autres nouvelles fonctionnalités, comme le commutateur de résultats en utilisant la Chaîne des ou de la multi-catch sont juste syntatic sucre et ne nécessitent pas de code octet changements. Par exemple, le multi-catch juste des copies de la catch-bloc pour chaque exception possible.

Le seul problème devrait être que les nouvelles classes introduites dans Java 7 manquants dans Android, comme AutoCloseable, donc je ne suis pas sûr si vous pouvez utiliser le try-with-resources fonctionnalité (quelqu'un l'a essayé?).

Tous les commentaires sur qui? Ai-je raté quelque chose?

12voto

Hosam Aly Points 14797

À partir de l’Android SDK v15, avec Eclipse 3.7.1, Java 7 est pas pris en charge pour le développement Android. Affectant la compatibilité source 1,7 mandats définissant la compatibilité des fichiers .class générés à 1,7, qui conduit à l’erreur suivante par le compilateur Android :

Android nécessite le niveau de conformité du compilateur 5.0 ou 6.0. Trouvé « 1,7' à la place. S’il vous plaît utiliser Android outils > Difficulté des propriétés de projet.

5voto

Nuno Cruces Points 71

Afin d'étendre la réponse ci-dessus par @KennyTM, si vous ciblez les 4.0.3 et plus (minSdkVersion=15), vous pouvez utiliser le caché Api par l'ajout de quelques classes de votre cible SDK android.jar.

Une fois que vous faites cela, vous pouvez utiliser try-with-resources sur tout Fermer, ainsi que de mettre en œuvre AutoCloseable dans vos propres classes.

J'ai fait un zip contenant les sources et les binaires de toutes les classes qui doivent être modifiés dans android.jar pour faire ces Api disponibles. Vous avez juste besoin de décompresser et d'ajouter les fichiers binaires à votre
android sdk/platforms/android-NN/android.jar

Vous pouvez le télécharger à partir d'ici: http://db.tt/kLxAYWbr

Il est également à noter que, dans les deux derniers mois, Elliott Hughes a fait quelques engage à Android arbre: fini AutoCloseable, a ajouté SafeVarargs, démasqués différentes Api, fixe Throwable protégées du constructeur et ajouté le support pour la version 51 fichiers de classe dans dx. Donc, il y a enfin des progrès en cours.

Edit (Avril 2014):

Avec la sortie du SDK 19 il n'est plus nécessaire de patch android.jar avec l'Api supplémentaires.

Ma meilleure méthode à utiliser try-with-resources dans une application qui cible 4.0.3 et plus (minSdkVersion=15) est d'utiliser Android Studio et Gradle, avec la configuration suivante:

android {
    compileSdkVersion 19
    buildToolsVersion '19.0.3'

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 19
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
}

Android Studio va se plaindre qu'essayez-avec-les ressources ne peuvent pas être utilisés avec cette API, mais mon expérience est qu'il peut. Le projet permettra de construire et d'exécuter sans problème sur les appareils avec 4.0.3 et au-dessus. Je l'ai connu aucun problème avec cela, avec une application qui a été installé dans les 500k+ périphériques.

Android Studio error

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X