Récemment j’ai refait un peu de JPA/Hibernate et j’ai eu besoin de mapper une relation many-to-many qui nécessite de stocker une information supplémentaire. Pour être concret, j’ai un objet Recette, un objet Ingredient et je souhaite associer une recette à un ingrédient. Ce qui est particulier dans mon cas c’est que j’ai envie de d’enregistrer en plus la quantité de cet ingrédient qui est utilisé dans ma recette de cuisine.
Rien de bien extraordinaire jusque là et je me souvenais avoir déjà géré ce genre de cas. Oui mais voilà, après quelques recherches sur les forums je n’ai trouvé aucune solution clé en main qui ne nécessite pas de parcourir les dizaines de commentaires et de les tester un à un.
Voici la solution que j’ai retenue, je suis bien sur ouvert à toute proposition permettant d’améliorer mon code ! Je ne présenterai ici que les mappings, je vous propose de retrouver l’intégralité des cas d’utilisations sur mon github (avec les Tests Unitaires et surtout le debug hibernate pour voir les requêtes qui passent).
L’idée générale est de découper le many to many en deux relations many-to-one/one-to-many avec l’utilsation d’un objet d’association qui va porter l’information que l’on souhaite rajouter (ici la quantité).
NB: je me sers de lombok pour générer les getter, setter et equals/hashcode de mes classes.
La classe Recipe:
package fr.valtech.many2many.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "recipe")
@EqualsAndHashCode(of = { "id", "title" }, callSuper = false)
public class Recipe extends AbstractEntity {
@Id
@Column(name = "recipe_id")
@GeneratedValue(strategy = GenerationType.AUTO)
@Getter
@Setter
private Integer id;
@Getter
@Setter
private String title;
@Getter
@Setter
@OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.recipe", cascade = CascadeType.ALL, orphanRemoval = true)
private Set ingredients = new HashSet();
public void addIngredient(RecipeIngredient i) {
i.setRecipe(this);
ingredients.add(i);
}
} |
La classe Ingredient:
package fr.valtech.many2many.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@Entity
@EqualsAndHashCode(of = { "id", "label" }, callSuper = false)
public class Ingredient extends AbstractEntity {
@Id
@Column(name = "ingredient_id")
@GeneratedValue(strategy = GenerationType.AUTO)
@Getter
@Setter
private Integer id;
@Getter
@Setter
private String label;
} |
La classe RecipeIngredient qui fait l’association:
package fr.valtech.many2many.domain;
import java.io.Serializable;
import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.Table;
import javax.persistence.Transient;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "recipe_ingredient")
@AssociationOverrides({
@AssociationOverride(name = "pk.recipe", joinColumns = @JoinColumn(name = "recipe_id", insertable = false, updatable = false)),
@AssociationOverride(name = "pk.ingredient", joinColumns = @JoinColumn(name = "ingredient_id", insertable = false, updatable = false)) })
@EqualsAndHashCode(of = { "pk", "amount" }, callSuper = false)
public class RecipeIngredient implements Serializable {
@Getter
@Setter
@Column(nullable = false)
private String amount;
@Getter
@Setter
@EmbeddedId
private RecipeIngredientId pk = new RecipeIngredientId();
@Transient
public Recipe getRecipe() {
return getPk().getRecipe();
}
public void setRecipe(Recipe recipe) {
getPk().setRecipe(recipe);
}
@Transient
public Ingredient getIngredient() {
return getPk().getIngredient();
}
public void setIngredient(Ingredient ingredient) {
getPk().setIngredient(ingredient);
}
public RecipeIngredient() {
}
public RecipeIngredient(Ingredient ingredient, String amount) {
setIngredient(ingredient);
this.amount = amount;
}
} |
Et enfin la composite primary key de la classe d’association:
package fr.valtech.many2many.domain;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Embeddable;
import javax.persistence.FetchType;
import javax.persistence.ManyToOne;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@Embeddable
@EqualsAndHashCode(of = { "recipe", "ingredient" }, callSuper = false)
public class RecipeIngredientId implements Serializable {
@Getter
@Setter
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Recipe recipe;
@Getter
@Setter
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Ingredient ingredient;
} |
Les “astuces” que j’ai mis un moment à comprendre sont:
- dans la classe RecipeIngredientId il faut absolument mettre les relations en LAZY pour éviter un stackOverFlow;
- dans la classe Recipe, la relation OneToMany doit absolument comporter le orphanRemoval = true, sinon la mise à jour et la suppression des RecipeIngredient se passent mal !
Bon tout n’est pas parfait et il faut gérer quelques trucs “à la main”.
Il faut nécessairement persister en base explicitement l’ingrédient que l’on veut utiliser dans une recette que l’on souhaite elle-même persister.
/**
* Parcourt l'ensemble des ingrédient pour voir si ils existe déjà en base ou non.
* @param recipe
*/
private void reatachIngredients(Recipe recipe) {
for (Iterator it = recipe.getRecipeIngredients()
.iterator(); it.hasNext();) {
RecipeIngredient ri = it.next();
Ingredient ingredient = ri.getIngredient();
if (ingredient.getId() != null && ingredient.getId() != 0) {
Ingredient reference = getEntityManager().getReference(
Ingredient.class, ingredient.getId());
ri.setIngredient(reference);
} else {
getEntityManager().persist(ingredient);
}
}
} |
Il faut écrire une requête JPQL pour récupérer la Recette dans son intégralité, si on veut par exemple la serialiser après (certaines relations avaient été mises en LAZY, notamment sur la PK).
Query q = getEntityManager().createQuery(
"select r from Recipe as r "
+ "left join fetch r.recipeIngredients as ri "
+ "left join fetch ri.pk as pk "
+ "left join fetch pk.ingredient "
+ "where r.id = :recipeId");
q.setParameter("recipeId", recipeId);
Recipe recipe = null;
try {
recipe = (Recipe) q.getSingleResult();
} catch (NoResultException nre) {
getLogger().info("no result found");
return null;
} |
Le code complet ici: https://github.com/jbcazaux/many2many

Dans quelques jours aura lieu la première édition de Devoxx France, la déclinaison francophone d’une des plus grande conférence pour les développeurs en Europe.
Elle est organisée par des développeurs indépendants et se déroulera à Paris du 18 au 20 Avril.
Plusieurs thèmes y seront évoqués
- Web, Mobile et le Cloud,
- Langages alternatifs sur la JVM
- Entreprise et pratiques
- Java, Java EE et Architecture
Le groupe Valtech, partenaire de cet événement, sera présent lors des 3 jours. Les consultants Valtech seront eux aussi présents et certains animeront même des présentations. Vous aurez l’occasion de connaître Incanter, une librairie de statistiques écrite en Clojure qui sera présenté par Claude Falguière ou de replonger dans le monde de la recherche d’information avec Majirus Fansi qui vous fera découvrir l’univers d’Apache Lucene et bien d’autres nouveautés.
Pourquoi l’équipe Valtech sera présente ?
- “Découvrir des nouveautés techniques“, Grégory, Développeur, Valtech
- “Participer à des ateliers et tester directement sur ma machine“, Frédéric, Développeur, Valtech
- “Échanger avec d’autres développeurs et partager mes connaissances“, Claude, Consultante senior, Valtech
- “Assister à Devoxx sans avoir à voyager dans un autre pays, c’est à ne pas rater“, Etienne, Scrum Master, Valtech.
Vous souhaitez partager, échanger et vous amuser…
Venez rencontrer l’équipe sur le stand Valtech !
Les 26 et 27 mai se déroulait au Grand REX une conférence java organisée par Zenika. Les intervenants se sont succédé pendant 2 jours sur des sessions de 60 à 90 minutes.
Cloudfoundry
Le premier à se prêter à l’exercice était Adrian Coyler, le CTO de springsource.
Dans sa présentation, il insiste sur les nouveaux besoins : de nouveaux modes d’interactions, de nouvelles façons d’accéder aux applications et donc de nouvelles façons de développer (langages récents, frameworks innovants) et déployer. Ainsi la virtualisation permet de gérer les besoins de dimensionnement des applications beaucoup plus rapidement. Les applications “sociales” sont aussi de plus en plus nombreuses.
Ainsi il présente le concept de PaaS et l’offre dans ce sens de springsource vmware : Cloud Foundry. Clound Foundry est open source (cloudfoundry.org), supporte plusieurs langages (Java, Grails, Rails, Ruby, JavaScript avec node.js). Clound Foundry propose également plusieurs services tels que MySql, MongoDB, Redis, …
3 formats sont proposés :
- le cloud public, par exemple pour déployer des applications ‘sociales’
- un cloud privé, que l’on peut installer sur ses serveurs
- puis le micro cloud que l’on peut installer sur son poste de travail pour tester !
Il nous montre ensuite comment interagir avec le cloud depuis une interface en lignes de commandes ou bien une vue de STS (l’IDE springsource basé sur eclipse).
Une réserve est tout de même émise sur la ‘scalabilité’. Ce n’est pas parce qu’une application est sur le cloud qu’elle est ‘scalable’. Le ‘design to scale’ prend alors toute son importance.
Pour conclure je reprendrai son “PaaS, this is where things are going”.
Orion
Boris Bokowski, ingénieur chez IBM et leader technique sur eclipse, a commencé sa présentation par le constat que beaucoup de choses étaient aujourd’hui réalisées dans le navigateur web : les spécifications, le suivi d’anomalies, la consultation du contrôle de version, la navigation dans le système de fichier,…
Bref, tout sauf l’IDE !
Il parle ensuite de la difficulté de développer et d’intégrer des plugins dans les IDE. Pareil pour les compilations en script avec lesquelles les dépendances sont difficilement gérables.
C’est donc le pari d’Orion que d’amener l’IDE dans le navigateur. Très vite, Boris passe à la démonstration pour nous présenter les fonctionnalités déjà implémentées.
Ainsi on trouve la classique indentation de code, le formatage, la complétion de code (simpliste), le debugging, la gestion de configuration (avec le support de git), …
L’intérêt majeur est en fait l’intégration très simplifiée de plugins grâce aux standards du web. Ainsi on peut utiliser des services proposés par d’autres sites comme google page speed, des générateurs de css, du formatage de code, des validateurs de normes de développement, des outils de génération d’expressions régulières, bien sûr le debugging avec par exemple firebug sous firefox,…
Il apprécie aussi, avec le sourire, le fait que la gestion des onglets est maintenant gérée par l’éditeur du navigateur et non plus par l’IDE.
Orion propose une version bêta publique pour chaque millestone et prévoit une première release pour juin.
Clojure
Howard Lewis Ship, le créateur d’entre autres Tapestry, HiveMind et Cascade, a fait une présentation du langage fonctionnel Clojure, qui s’exécute dans la JVM. La session était d’un haut niveau et la syntaxe du langage ne rendait pas la tâche aisée pour le néophyte.
C’était donc une première approche de ce langage avec quelques exemples de fonctions pourtant répandues dans ce genre d’exercice, mais qui auraient tout de même mérité que l’on s’attarde un peu plus sur chacun d’entre elles.
Gestion de la mémoire
Une session sur la gestion de la mémoire, du processeur jusqu’au langage java en passant par l’OS, qui m’a laissé perplexe (même si cela m’a rappelé quelques cours d’architecture). Aux dires des personnes qui avaient invité Jevgeni Kabanov, le CTO de JRebel, c’est au 4ème visionnage de la session que l’on comprend vraiment ce que raconte cet intervenant survolté.
SQLFabric
L’après-midi a continué par la présentation de SQLFabric. J’ai surtout retenu qu’aujourd’hui, tout le monde ne développait pas un site qui gère des centaines de milliers d’utilisateurs avec des péta octets de données et donc qu’il ne fallait pas tomber dans le choix systématique et à la mode du NoSQL.
WebSockets
La journée s’est finie par une brillante présentation des WebSockets par Brad Drysdale de chez Kaazing.
Brad commence par le constat que nos applications web ne font pas du temps réel, ou alors de façon vraiment pas efficace et/ou très coûteuse en bande passante ou encore en passant par des plugins. Mais ces solutions de contournements ne sont pas prêtes pour le “cloud” car elles ne sont pas “scalables”.
L’enjeu est donc d’avoir des connexions “full duplex” entre les clients et le serveur et non plus comme aujourd’hui simplement “half duplex” en faisant du polling, du long polling ou encore du streaming.
La réponse à toutes ces problématiques est donc l’utilisation des websockets, qui viennent avec HTML5.
En effet le mécanisme implique une consommation drastiquement diminuée de la bande passante (2 octets en plus par trame une fois le protocole négocié contre au minimum 800 octets pour chaque trame HTTP).
Les autres avantages abordés sont la standardisation du protocole, du full duplex sur une seule socket, le support des firewalls, proxy et routeurs sans problème, la possibilité de récupérer des données depuis plusieurs sites, un seul port ouvert (le même que HTTP), et enfin la possibilité de sécuriser les flux comme HTTPS le fait, via TLS.
Le 14 Avril, Valtech accueillait l’anniversaire de Duchess France.
Une soirée très animée organisée principalement autour du Trivial Java, un jeu basé sur des questions de la certification Java et quelques thèmes plus ouverts (Veille Techno, Histoire, Frameworks, Agile). Il a permis à chacun de réviser ses connaissance et d’apprendre tout en s’amusant. Une technique très efficace.
Des cadeaux ont également été offerts à quelques chanceux et l’équipe gagnante est repartie avec des jolies mugs Duchess France.
Duchess France a aussi annoncé l’organisation d’un événement récurrent, La Marmite dont le but sera de mettre les mains dans le code, participer à des projets Open Source et améliorer sa pratique des outils. Bien sûr les autres actions, l’Avant JUG, les groupes de travail, le blog, le calendrier restent d’actualité.
Vous trouverez plus d’information sur le site de Duchess France.

Le 14 Avril, Valtech accueille le premier anniversaire de Duchess France dans l’auditorium du 103 rue de Grenelle.
Cette communauté a été crée dans le but de rendre les femmes qui font du développement Java plus visibles et pour contribuer à lutter contre certains stéréotypes. En un an Duchess France a permis à des dizaines de développeuses Java de se mettre en contact, de s’entraider et favorisé leur intégration dans d’autres communautés de développeurs Java telles que le Paris JUG. Duchess France est ouverte à tous.
Cette première soirée organisée par Duchess France commencera à 19h par une courte présentation des projets pour l’année à venir puis place à une série de jeux sur Java et à des surprises jusqu’à 22h.
Vous trouverez toutes les informations et le lien pour l’inscription sur le site de Duchess France. Cette soirée est ouverte à tous les passionnés du langage Java, hommes ou femmes.
Publié le 24/01/2011, par Nicolas Bétheuil dans Tutoriel | 1 Commentaire
Je vais vous faire part dans ce nouveau billet de mon incommensurable expérience sur GAE et d’un écosystème particulier, le mien. Pour reformuler, ce que je vous propose ici est un REX. J’ai toujours adoré cet acronyme, très parlant, d’une phonétique explosive. C’est le genre de document qui revient vous mordre même une fois que vous l’avez mis à la niche. Pour ceux qui ne connaissent pas, c’est un document que l’on vous demande de rédiger quand vous vous êtes planté pour ne pas vous planter une deuxième fois. De manière plus positive, on a toujours dit que c’est en tombant que l’on apprends à marcher.
Lire la suite »
Valtech était à Devoxx 2010, une longue semaine de travail et de discussion et un retour d’Anvers fatiguée mais bourrée d’idées.

Tout d’abord félicitations à Stephen Janssen et à l’équipe de Devoxx : un cinéma avec des fauteuils confortables, une logistique pour 3 000 personnes, des conférences intéressantes sur des sujets variés et la retransmission sur Parleys pour que ceux qui n’ont pas fait le déplacement puisse profiter des meilleures présentations.
Devoxx 2010, c’est un programme quotidien très chargé (5 jours de 9h30 à 22h pour les plus assidus et jusqu’à 6 salles en parallèles) donc énormément de sujets et je ne reviendrai pas sur tout en détail.
C’est aussi beaucoup de discussions entre les sessions et plus tard en soirée sur les langages, notre métier et diverses choses qui font que des réseaux se forment.
Que contenait la fournée 2010 ?
D’abord les annonces officielles d’Oracle sur Java EE 6 et Java SE 7 ainsi que sur le devenir d’Open JDK. Open JDK restera et Java sera plus simple, plus pratique et plus facile à utiliser. Plusieurs présentations JPA/Hibernate viennent compléter ce tableau. Les évolutions les plus attractives de Java SE comme le projet Lambda (langage fonctionnel) ou le projet Jigsaw (modularité et gestion des dépendances) sont reportés à Java SE 8. La vie semble reprendre après une période difficile.
Un gros thème NoSql cette année, même si ça n’est pas strictement du Java. Cloudera (Hadoop, HBase), Cassandra, MongoDB, Infinitest et plusieurs grands site Web utilisateurs de bases NoSql avaient fait le déplacement. Des présentations assez inégales mais qui donnaient l’opportunité aux développeurs Java de découvrir cet univers. Dans ce thème aussi une présentation très intéressante des fondamentaux du cache distribué et Ehcache The essence of Caching.
Autre gros thème cette années, les interfaces utilisateur avec des sujets sur Android, HTML5 et Flex avec la même préoccupation qui revient constamment “On n’est pas obligé de faire des IHM moches avec Java”. Une très belle présentation de Romain Guy et Chet Haas Dive into Android avec du code en live et des explications sur le graphisme avec Android.

Bien sûr quelques sujets sur les fondamentaux Java sur les bonnes pratiques du développeur, avec un zeste de Cloud cette année? J’ai un peu zappé car d’autres sujets mon plus intéressé mais j’ai un peu regretté de n’avoir pu accéder à aucune des présentations de Joshua Bloch (Effective Java, Java Puzzle), trop de monde à chaque fois. Un peu de Scala et de Groovy/Grails mais les langages n’étaient pas très représentés.
Dans les présentations plus processus une mention spéciale pour From Dev/Ops to DevOps. Amazing the difference one character can make (en photo). DevOps est un mouvement émergeant qui vise à rapprocher les équipes de développement et les opérations (la production en français) pour mieux résoudre les problèmes de déploiement et de suivi de production. Le sujet avait aussi été abordé au CITCON en relation avec le Continuous Deployment (aussi présent à Devoxx mais on doit faire des choix vu le nombre de sujets et je ne l’ai pas vue). On en reparlera !
Et pour finir un peu d’humour les derniers jours avec les enregistrements Live des podcasts Java Posse et Les Cast Codeurs.
On attend avec impatience l’édition 2011, mais en attendant voilà des dizaines de pistes à explorer avant l’années prochaine.
Le Paris JUG fête ses deux ans avec une soirée spéciale !
Le Paris JUG est le groupe d’utilisateurs du langage Java qui se retrouve mensuellement à Paris.
Cette soirée aura pour thème l’Open Source en France. Les représentants de Obeo, XWiki, Développons en Java, jCaptcha, eXo Platform, jax-doclets, Play! framework serons là pour vous présenter leur projet et vous pourrez les retrouver sur les stands pour discuter avec eux.
La soirée d’anniversaire aura lieu le Mardi 9 février, de 18h45 à 23h00 exceptionnellement dans les locaux de la Sorbonne Paris IV dans le 17ième. Elle sera suivie d’une 3ième mi-temps qui aura lieu au Dôme de Villiers (4 Avenue de Villiers, 75017 Paris).
N’oubliez pas de vous inscrire 2ième anniversaire du Paris JUG pour l’accès à la conférence et si vous le souhaitez pour la 3ième mi-temps.
L’équipe du JUG vous attend nombreux et nombreuses pour cette soirée exceptionnelle.
2ème anniversaire du Paris JUG
Ce tutoriel a pour objectifs de mettre en place un environnement de développement Android 1.6 sous Eclipse.
A la fin de ce tutoriel vous saurez :
- Mettre en place Eclipse 3.5 avec le plugin Android
- Créer une application Android
- Déployer une application Android dans l’émulateur de votre choix
Installer Eclipse Galileo
Rien de plus simple, il suffit de le télécharger à http://www.eclipse.org/downloads/ et de choisir la version “Eclipse IDE for Java EE Developers” pour votre système d’exploitation.
Une fois téléchargé, pour l’installer il vous suffit de le dézipper !
Installer Android SDK 1.6r1
Commencez par vous rendre à l’url : http://developer.android.com/sdk/ et choisissez la version correspondant à votre plateforme.
Pour l’installer, c’est comme Eclipse, il suffit de dézipper l’archive dans le répertoire de votre choix; dans le cadre de ce tutoriel, j’appellerai ce répertoire $ANDROID_HOME_DIRECTORY.
Astuce : pour avoir accès aux outils Android dans votre “Path” (variables d’environnement), vous pouvez ajouter le répertoire $ANDROID_HOME_DIRECTORY/tools à votre Path. Sous Windows : dans les propriétés de l’ordinateur(raccourci : Windows+Pause ou clique droit sur le poste de travail -> propriétés) cliquez sur l’onglet “Avancé”, de là, sélectionnez “Variables d’environnement” et ajoutez votre chemin d’installation $ANDROID_HOME_DIRECTORY/tools à votre path.
Vous pourrez ainsi avoir accès aux outils android dans toute fenêtre de commande.
Pour tester, ouvrez une fenêtre de commande : Démarrez -> Executer->cmd, et tapez adb, vous devriez avoir ceci :
C:\Documents and Settings\anthony.dahanne>adb
Android Debug Bridge version 1.0.20
-d - directs command to the only connected USB device
returns an error if more than one USB device is present.
-e - directs command to the only running emulator.
returns an error if more than one emulator is running.
-s - directs command to the USB device or emulator with
the given serial number
-p - simple product name like 'sooner', or
a relative/absolute path to a product
out directory like 'out/target/product/sooner'.
If -p is not specified, the ANDROID_PRODUCT_OUT
environment variable is used, which must
be an absolute path.
devices - list all connected devices |
Si vous ne voulez pas / pouvez pas mettre à jour votre chemin, vous pourrez toujours accéder à l’outil adb par exemple en tapant dans la fenêtre de commande : $ANDROID_HOME_DIRECTORY/tools/adb (en remplaçant ADB_HOME_DIRECTORY par votre répertoire d’installation du SDK Android)
Installation du plugin Eclipse Android SDK
Démarrez Eclipse, et créez un nouveau workspace en choisissant un répertoire au choix (le workspace contiendra tous vos projets)
Juste après, rendez vous dans “Help->Install new software…”
Cliquez sur “Add new site” pour ajouter le site du plugin Android : choisissez le nom que vous souhaitez, et l’url suivante : https://dl-ssl.google.com/android/eclipse/

Ceci étant fait, sélectionnez les 2 cases : DDMS et android tools for eclipse, cliquez sur next, acceptez la licence et c’est fini !

Ecllipse vous demande de redémarrer, acceptez, et au redémarrage d’Eclipse configurez votre plugin Android en allant dans Window->Preferences->Android, de là indiquez votre $ANDROID_HOME_DIRECTORY
Vous pouvez maintenant créez un nouveau projet Android 1.6
Astuce : si vous préférez, vous pouvez télécharger le plugin sans passer par le “Update Manager d’Eclipse”, dans ce cas là, décompresser à la racine de votre instalaltion d’Eclipse le’archive suivante :
http://dl.google.com/android/ADT-0.9.3.zip
Au redémarrage d’Eclipse, il vous sera demandé de configurer Eclipse pour qu’il sache où se trouve le SDK Android :

Pour cela, vous devez vous rendre dans Window->Preferences->Android et indiquer le répertoire de votre SDK
C’est bon, vous êtes prêt pour créer votre premier projet Android !
Création de votre premier projet HelloAndroid
Nous allons pour cela utiliser le plugin eclipse Android.
Cliquez sur File->New->Android Project (ou alors File->New->Project et sélectionner Android Project)
Rentrez les informations de votre projet, en particulier, choisissez la version 1.6 de l’API (la plus récente à ce jour, Donut); cependant, sachez que tous les possesseurs de téléphone Android n’ont pas encore mis à jour vers Donut, vous pouvez alors choisir la version 1.5 (Cupcake) pour un maximum de compatibilité

Astuce : vous aurez sans doute remarquer la présence de 2 autres options : Google APIs; ces versions, embarquent, en plus des librairies standards d’Android, les APIs des produits propriétaires Google, comme, par exemple, l’API Maps (si vous voulez afficher une carte Google Maps dans votre application, vous devrez donc choisir Google Api)
Cliquez sur “Finish”, le plugin vous génère alors votre projet, dans mon cas HelloAndroid
Nous allons commencer par observer la classe HelloAndroid.java, qui constitue l’unique activité (considérez pour l’instant qu’il s’agit d’un écran; est une activité une classe qui hérite de Activity) de votre projet :
package com.valtech.helloandroid;
import android.app.Activity;
import android.os.Bundle;
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
} |
Astuce : vous vous rendrez compte, en suivant la classe Activity avec ctrl+click que vous n’avez pas accès au code source des classes Android.
Or le projet est open source, il serait dommage de se passer d’une telle aide !
Pour voir le code source sous eclipse, telechargez ce fichier zip :
http://rgruet.free.fr/public/android-1.5-cupcake-src.zip (il contient les sources d’Android 1.5) et renommez le en sources (sans suffixe de nom de fichiers)
Ensuite, copiez le dans $ANDROID_HOME_DIRECTORY/platforms/android-1.5

Et c’est fini ! Essayer donc un ctrl+click dans Eclipse sur n’importe quelle classe du framework Android, et vous verrez le code source ! (après éventuellement un redémarrage d’Eclipse)

Idem pour la version 1.6, vous pouvez télécharger les sources de cet emplacement : http://rgruet.free.fr/public/android-1.6_r1-donut-src.zip (à renommez en sources dans $ANDROID_HOME_DIRECTORY/platforms/android-1.6)
Le code de HelloAndroid.java stipule qu’à la création de l’activité, on va définir son contenu avec la mise en page (layout) main.
Astuce : R.layout.main est défini dans une classe générée, R qui se présente (pour le moment) ainsi :
public final class R {
public static final class attr {
}
public static final class drawable {
public static final int icon=0x7f020000;
}
public static final class layout {
public static final int main=0x7f030000;
}
} |
Toutes les valeurs définies dans ce fichier représentent des ressources, souvent définies sous la forme de fichiers XML (ainsi la valeur main correspond à main.xml dans le dossier res/layout)
Pourquoi est ce fait ainsi ? car les ressources sont traduites en code compilé, ce qui optimise l’empreinte mémoire de vos applications.
Le layout (mise en page) de votre activité est donc définie dans res/layout/main.xml :
Je vous laisse retrouver la valeur de @string/hello dans les ressources !
On voit ici que un TextView (un label) a été défini, ainsi, lors du déploiement de HelloAndroid, on devrait s’attendre à voir un écran avec un label
D’ailleurs pour que cette activité soit activée, elle doit être référencée dans le manifest de votre projet : AndroidManifest.xml
Vous l’avez compris, le manifest est le fichier le plus important de votre projet : il référence toutes vos activités (et bien plus !)
Nous pouvons maintenant passer au déploiement du projet dans un émulateur.
Déploiement de votre projet Android
Votre projet peut être déployé sur un téléphone équipé d’Android, ou sur un émulateur.
Pour celà, cliquez droit sur votre projet et sélectionnez “Run as Android Application.”

Comme il s’agit de votre premier déploiement, le plugin Android vous propose de créer une nouvelle instance d’émulateur: un AVD (Android Virtual Device) :

Une fois votre AVD paramétrée, cliquez sur “Create Avd”, votre AVD est créée, vous pouvez alors la sélectionner pour déployer votre projet sur cette dernière ! (après éventuellement avoir fait un “Refresh”)

Astuce : il n’est pas nécessaire de redémarrer votre AVD à chaque modification de votre projet !En cliquant sur Run as Android application, votre projet se re déploiera dans votre AVD existante.
Astuce : pour changer l’orientation de votre AVD , composez Ctrl+F11
Astuce : il existe plusieurs “skins” pour votre AVD : en effet, si vous souhaitez créer votre AVD avec une skin différente, par exemple celle proposée par Archos pour leur futurs tablet pc android, vous pouvez télécharger la skin : http://appslib.com/download/a5_horiz.zip, la dézipper dans $ANDROID_HOME_DIRECTORY/platforms/android-1.5/skins

En redémarrant Eclipse, et en cliquant sur l’icone du téléphone, vous pourrez créer une nouvelle AVD qui correspondra à une cible Android avec une plus haute résolution que celle d’un téléphone: idéal pour tester vos applications sur plusieurs cibles différentes !
Pour modifier votre configuration de lancement, allez dans Run-> Run configurations …, et sous l’onglet Target de votre projet, vous pourrez choisir quelle sera l’émulateur à lancer par défaut !
Astuce : si votre projet Android est défini comme étant un projet android 1.6, il faut le déployer dans un AVD (émulateur) version 1.6 ! (un projet Android 1.5 se déploie aussi bien dans un AVD 1.5 que 1.6)
Félicitations ! Votre premier projet, HelloAndroid, est déployé dans votre émulateur !

Références :
Mardi 27 Septembre 2009, j’ai animé un cours du soir (durée 2h. environ) dans les locaux de Valtech, à destination des consultants Valtech Technology Consulting.
On était presque une dizaine, et dans une atmosphère conviviale et intéressée (plusieurs membres de l’audience avait leur téléphone Android sur eux, çà aide !), j’ai déroulé ma présentation, dont voici les diapositives (format OpenOffice OpenDocument sous licence Creative Commons) et les TPs :
cours_du_soir_android_22_09_2009
workspace_android
En gros, nous avons parcouru :
- l’environnement de développement sous Eclipse
- les activités et les intents
- le broadcastReceiver de SMS
Le prochain cours du soir sera présenté par Sadek Drobi et parlera de Scala, vivement la semaine prochaine !