android

[Développement] Application Android

posté le 23 July 2014 à 14:37

Salut les geeks (oui, si vous avez cliqué malgré le titre, vous êtes irrémédiablement un geek, voir un nerd), et attention: voilà du wall of text!

Comme je me suis lancé dans l'aventure des applications mobiles depuis quelques mois, et que j'ai appris pas mal de choses en cours de route, je me suis dit que ça pouvait valoir la peine d'écrire un post pour:
1) partager avec ceux que ça pourrait intéresser les trucs que j'ai appris (en particulier des outils/librairies sympa comme tout)
2) apprendre vos propres trucs et astuces

J'ai mis Android dans la titre, parce que c'est mon focus du moment, mais si vous avez des trucs et astuces qui peuvent s'appliquer aux applications mobiles dans l'absolu, ça marche aussi. Par exemple (pas tout à fait au hasard: je vais avoir à faire ça dans pas longtemps donc si quelqu'un sait comment faire ça, je suis preneur d'un peu d'aide): vous connaissez un super outil pour mettre en place vite et bien un webservice en java hébergé sur l'AppEngine de google (et pouvant donc servir de backend à une application web ou mobile), allez-y, dites nous tout!

Et histoire de démarrer le truc, voilà ma première pierre à l'édifice:

Recrute majordome, mobilité et capacité à rédiger des rapports exigées

Déjà, et contrairement à ce que j'avais lu sur plusieurs sites (dont l'habituellement raisonnablement bien renseigné openclassroom, ex site du zero), il est tout à fait possible de mettre en place un environnement d'intégration continue pour un projet Android. S'il y en a qui ne savent pas ce que c'est que l'intégration continue et pourquoi c'est génial et qu'on ne peut plus s'en passer une fois qu'on y a goûté, faites-moi signe dans les commentaires (en particulier si vous bossez sur un projet avec plus de 4 personnes sur la même base de code).


Pour cela, il faut:
 - un SCM (SVN ou Git, ma préférence allant à ce dernier depuis que je l'ai adopté en janvier dernier, si ça intéresse quelqu'un je pourrais expliquer pourquoi)
 - un outil de compilation (Gradle, Ant ou Maven, je connais déjà Maven donc je reste sur celui-là mais à priori c'est possible avec les 2 autres quasiment de la même manière)
 - un serveur d'intégration continue (vous posez pas de question, c'est Jenkins qu'il vous faut)

La difficulté réside dans la capacité à faire compiler le projet avec l'outil de compilation. Par compiler, j'entends; compiler les fichiers de code .java en .class (ça Maven sait le faire en natif), produire le .dex qui les réunit tous, puis intégrer le .dex et les ressources dans l'apk (signé ou non, selon qu'on est en debug ou en release), déployer et executer sur un device (c'est à dire un téléphone ou un tablette connectée en USB et avec le mode debug activé) ou sur un émulateur (parce qu'on a pas tous les moyens d'avoir 15 devices différents pour tester toutes les tailles d'écran et toutes les versions d'android), tout ça x2 puisqu'il faut un projet "principal" (l'application en elle-même) et un projet de test (vous testez votre code, n'est-ce pas?).

Pour ma situation (Maven + Jenkins), il faut 3 outils:
1) Un "outil" appelé "Maven Android SDK deployer", qui va essentiellement ajouter à votre repository Maven local les jar des différents versions d'android (et des extra, genre les Google APIs si vous vous utiliser Google Maps, etc), sachant que sa plus-value principale est surtout sur ces extra (les jar des principales version d'android étant désormais ajoutés par google sur Maven Central).
2) un plugin maven: le bien nommé "Android Maven Plugin" qui va ajouter à maven quelques goal bien pratiques, tels que "android:deploy" pour déployer un apk sur un device ou un émulateur, ou encore "android:run" pour lancer l'execution. Et aussi un format de packaging supplémentaire "apk" (sachant que maven gère nativement "jar" et "war" il me semble).
3) un plugin Jenkins: le (lui aussi bien nommé) "Android Emulator Plugin" pour automatiser la création d'émulateurs, leur paramétrage, obtenir les résultats d'une exécution, bref, tout ce qu'il faut pour de l'intégration continue. Pardonnez moi de rester flou sur ce point, je suis tout juste en train de le mettre en place, je ne maitrise pas encore super bien (mais encore une fois, si ça intéresse du monde, je pourrais développer au fur et à mesure de mes avancées).

Tout ça c'est chouette comme tout, vous allez pouvoir mettre en place une intégration continue de votre projet Android, et tout sera pour le mieux dans le meilleur des mondes...

Plus vite nestor ou je te remplace par un mouton réplicant

... enfin presque, parce que bon, même comme ça, l'intégration continue ne va pas se déclencher toute les 3 minutes non plus et même si c'était le cas, lancer un émulateur, déployer l'apk dessus et lancer l'appli ça prend au moins quelques minutes dans le meilleur des cas. Donc pour dérouler des tests de non régression fonctionnels ça va encore, mais pour du test unitaire c'est pas idéal.

Et c'est là qu'intervient ma découverte d'hier (qui a motivé ce post interminable): Robolectric. Cette petite merveille (gratuite et open source, comme tous les outils/plugins cités jusque là) "remplace" le fichier android.jar habituel (et qui vous jettera des "java.lang.RuntimeException : Stub!" à la tronche si vous essayez de le faire tourner dans un JVM classique car il ne contient aucun vrai code, uniquement les déclarations d'API pour vous permettre de compiler) par ce qu'il faut (non, j'en sais rien et je sais même pas comment, mais ça marche) pour que vous puissiez faire tourner votre code de test dans une JVM classique, par exemple (au hasard) celle de votre IDE préféré (Eclipse pour moi, et probablement 90% des dveloppeurs d'appli Android). Ca veut dire que moyennant un peu de paramétrage de raccourcis clavier, il y a moyen d'exécuter vos tests unitaires quasiment à chaque fois que vous sauvez votre fichier de code, et qu'ils seront exécuté presque instantanément. En ce qui me concerne, j'ai re-configuré Ctrl+D pour lancer mes tests unitaires, ce qui fait que je fais très souvent Ctrl + S, Ctrl + D sans même lever le doigt de la toucher contrôle, vous allez voir que ça devient un réflexe assez vite (en vrai, je fais en général Ctrl + O, Ctrl + F, Shift + Ctrl + S, Ctrl + D, pour respectivement: organiser/nettoyer les import, formatter/indenter le code, sauver tous les fichiers ouverts et lancer les tests unitaires, les 3 premiers étant des raccourcis standard eclipse).

Attention, ça ne remplace pas des "vrais" tests fonctionnels sur émulateurs (au pire) et sur device (au mieux), ça vient les compléter. Et si vous ne pouvez pas vous permettre le luxe de faire les deux (même si d'après mon expérience personnelle c'est largement rentable sur le long terme), j'ai tendance à conseiller les test unitaires en priorité, car leur execution quasi synchrone avec l'écriture du code permet d'éviter de s'éloigner de l'objectif en cours de réalisation pour l'heure/la journée. Tandis que les tests fonctionnels délimitent les grandes lignes attendues du point de vue utilisateur que vous allez peut-être mettre des semaines voire des mois à atteindre...

La prochaine fois (c'est à dire: quand j'aurais eu le temps de tester) je vous parlerer de Dagger, une chouette librairie pour faire de l'injection de dépendance sur Android (et pour les suivantes, j'ai au menu: Mockito, un framework de mock pour compléter Robolectric, Otto, une librairie de bus évennementiel à la guava, ButterKnife pour faire l'injection des vue dans une activité, Retrofit, un client REST type safe pour android et plus largement pour Java et FestAndroid, une collection d'assertion AssertJ pour android).

Voilà, c'est tout pour aujourd'hui!

Des questions? Des avis? Vous avez rien compris mais ça vous intéresse et vous voudriez que j'explique un terme ou un concept précis? Les commentaires sont la pour ça, lâchez-vous!