Développer des applications Android avec Maven

Il y a quelques mois de cela, je vous parlais d'industrialisation des développements Android. Tout n'était pas parfait pour être vraiment productif, notamment l'intégration entre les outils de build et l'IDE. Qu'en est-il aujourd'hui ? Peut-on enfin être aussi efficace sur du développement Android que sur du Java standard ? Ce sont les questions auxquelles je réponds dans cet article.

Maven enfin utilisable... ou presque !

Lorsque nous l'avions testé avant l'été, nous avions rencontré des problèmes avec le trio Maven / Android / Eclipse. L'intégration Eclipse/Android se passe très bien avec ADT et Eclispe/Maven fonctionne à merveille avec m2eclipse. L'intégration Maven/Android était un peu compliquée de par l'absence des jar Android sur le repo central mais fonctionnait tout de même (avec le plugin maven-android-plugin). Le véritable point noir était l'intégration des trois.

Aujourd'hui, tout cela a évolué et le plugin m2eclipse-android-integration (qui existait déjà à l'époque) fonctionne !

Il est donc bien plus simple de travailler avec nos outils habituels (je ne rentre pas dans les détails, chacun des outils est globalement bien documenté si vous avez un soucis) :

Installation

  • Premièrement, récupérez et installez chacun des outils suivant : Eclipse, Maven, le SDK Android et les plugins ADT (Android Development Tools), m2eclipse et m2eclipse-android-integration pour Eclipse.

  • Définissez les variables d'environnements nécessaires : JAVA_HOME, ANDROID_HOME et le PATH vers les binaires (mvn et les tools Android).

  • Créez votre projet Android dans Eclipse comme vous le faites habituellement.

  • Transformez ensuite votre projet en projet Maven (click droit sur le projet / Maven / Enable Dependency Management). Il devrait automatiquement vous créer un pom.xml très basique dans lequel il va falloir ajouter quelques éléments pour pouvoir utiliser le plugin maven-android-plugin.

  • Dans le settings.xml de Maven, ajoutez la configuration suivante, cela vous permettra d'utiliser ce plugin sans avoir à spécifier le groupId :

    <pluginGroups> 
        <pluginGroup>com.jayway.maven.plugins.android.generation2</pluginGroup>
    </pluginGroups>
    
  • Au niveau du pom, plusieurs choses avant d'être complètement opérationnel. Au niveau du packaging, précisez que vous créez un apk. Configurez ensuite le plugin de jayway comme suit (plus d'options et d'infos ici) :

    <build>
      <sourceDirectory>src</sourceDirectory>
      <plugins>
        <plugin>
          <groupId>com.jayway.maven.plugins.android.generation2</groupId>
          <artifactId>maven-android-plugin</artifactId>
          <version>2.6.0</version>
          <configuration>
            <sdk>
              <path>${env.ANDROID_HOME}</path>
              <platform>8</platform><!-- android 2.2 -->
            </sdk>
            <deleteconflictingfiles>true</deleteconflictingfiles>
          </configuration>
          <extensions>true</extensions>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>2.3.2</version>
          <configuration>
            <source>1.6</source>
            <target>1.6</target>
          </configuration>
        </plugin>
      </plugins>
    </build>
    
  • Et voilà ! Votre projet Android est mavenisé et intégré à Eclipse (il vous faudra peut être ajouter le répertoire "gen" aux répertoires sources d'Eclipse). Il ne reste plus qu'à ajouter des dépendances...

Problèmes de dépendances

Peu de dépendances sur le repo central

Sur ce point, on n'est pas encore au niveau des projets java habituels. En effet, le nombre de dépendances Android qui sont disponibles sur un repo ou un autre est encore assez mince. Alors on a Android lui même, après l'avoir attendu très longtemps :

<dependency>
  <groupId>com.google.android</groupId>
  <artifactId>android</artifactId>
  <version>2.2.1</version>
  <scope>provided</scope>
</dependency>

On a également les dépendances java habituelles (commons-* et tout ce que vous pouvez trouver sur central), pour peu que ça compile sur Android. Mais à côté de ça, admob, google analytics, ... et même google maps ne sont pas disponibles et devront être ajouté à la main :

mvn install:install-file -Dfile=$ANDROID_HOME/add-ons/addon_google_apis_google_inc_8/libs/maps.jar -DgroupId=com.google.android.maps -DartifactId=maps -Dversion=8_r1 -Dpackaging=jar

Bien sûr, si vous avez un référentiel d'entreprise type nexus ou archiva, ca simplifiera le travail aux développeurs.

Librairies

Autre problème, les librairies Android, des projets déclarés "is library" dans Eclipse et simplement utilisés comme dépendances de projet (par exemple Greendroid ou l'Api Facebook...). Le plugin maven-android-plugin prévoit bien de générer un package apkSources, censé être ensuite utilisable comme dépendance par un autre projet... Le soucis, c'est que le fichier R.java n'est pas disponible dans le package et par conséquent la compilation échoue.

Une issue a été créé sur ce point et une solution officieuse existe : Une branche alternative du projet jayway a été créé et propose le packaging apklib qui corrige le problème de compilation.

Il vous faudra donc maveniser les librairies que vous utilisez si elles ne le sont pas déjà. Prenons l'exemple de greendroid. Dans ce projet, ajouter un pom qui aura la définition suivante (ainsi que la conf mentionnée plus haut) :

<groupId>com.greendroid</groupId>
<artifactId>greendroid</artifactId>
<version>1.0</version>
<packaging>apklib</packaging>

Exécutez la commande mvn install pour déployer l'apklib dans le repo local (com/greendroid/greendroid/1.0/greendroid-1.0.apklib). Enfin, configurez votre projet :

<dependency>
			<groupId>com.greendroid</groupId>
			<artifactId>greendroid</artifactId>
			<version>1.0</version>
			<type>apklib</type>
		</dependency>

Ca nécessite un peu de boulot mais ca fonctionne. J'ai demandé quand on pouvait espérer cette fonctionnalité dans la branche principale du plugin mais aucune réponse n'a été fournie.

Un plugin complet

Une fois ces soucis de compilation et de dépendances résolues, pas mal de choses sont ensuite possibles avec le plugin maven-android-plugin : deployer un apk sur l'émulateur ou un téléphone branché en USB (mvn deploy), signer et "zipaligner" un apk avant un déploiement sur le Market, et tout un tas d'autres commandes dont vous trouverez la liste ici (et notamment les tests dont nous allons parler juste après).

Associé à cela, Hudson (pardon, Jenkins) et le plugin Android dont nous avions parlé la dernière fois, et vous êtes paré pour développer des applications Android d'Entreprise !

Conclusion

Tout n'est pas encore tout rose et quelques réglages manuels sont nécessaires pour avoir un environnement prêt à l'emploi. Mais une fois ces manipulations effectuées, vous voilà parés pour développer vos applications Android avec Maven. Dans mon dernier article à ce sujet, je n'étais pas totalement favorable à son utilisation (peu de librairies, environnement non fonctionnel). Je reviens sur ce choix aujourd'hui du fait du nombre grandissant de librairies utilisées sur nos projets (greendroid, spring-android, analytics, jackson, ...) et de l'évolution des outils. Les projets Android se complexifient et un outil comme Maven devient désormais nécessaire. Quid de la qualité de ces projets ? ... dans un prochain article !