|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: Tour d'horizon des frameworks java pour Android |
| 4 | +author: johanpoirier |
| 5 | +tags: [android, framework, java] |
| 6 | +published: false |
| 7 | +--- |
| 8 | + |
| 9 | +L'API d'Android est vaste et plutôt bien fournie. Mais il nous arrive |
| 10 | +régulièrement d'écrire toujours le même code (plus ou moins bien) pour |
| 11 | +effectuer certaines tâches de base (récupération et mise à jour de View, |
| 12 | +traitements BDD, récupération de ressources, ...). La communauté Android, |
| 13 | +qui est très active, nous propose déjà beaucoup de frameworks différents |
| 14 | +pour nous aider à développer plus facilement et plus proprement. Je vous |
| 15 | +propose donc de faire un petit tour d'horizon des frameworks que j'ai pu |
| 16 | +découvrir (et tester pour certains). |
| 17 | + |
| 18 | +Nous allons procéder par thèmes : |
| 19 | + |
| 20 | +## Dependency Injection |
| 21 | + |
| 22 | +### [RoboGuice](http://code.google.com/p/roboguice) |
| 23 | + |
| 24 | +RoboGuice en version 1.1 est basé sur Google Guice 2.0. Google Guice est |
| 25 | +un framework léger d'injection de dépendances pour les applications Java. |
| 26 | +Il est intégré à RoboGuice dans sa version sans AOP (donc sans |
| 27 | +génération dynamique de bytecode). |
| 28 | +Ce framework nous permet d'injecter directement des vues (View), |
| 29 | +ressources, services systèmes, etc... dans nos activités et autres |
| 30 | +classes de nos applications Android. Cela nous permet d'éliminer beaucoup |
| 31 | +de bouts de codes répétitifs et améliore grandement la lisibilité du |
| 32 | +code. |
| 33 | +Côté performances, je n'ai pas eu le temps de réaliser un vrai benchmark |
| 34 | +mais cela ne saurait tarder. L'injection se faisant au runtime, il est de |
| 35 | +bonne augure de se poser la question de l'impact d'un tel framework sur |
| 36 | +l'exécution d'une application sur un mobile. La taille de la librairie |
| 37 | +est d'environ 550Ko, ce qui non négligeable (surout pour les "vieux" |
| 38 | +terminaux android). |
| 39 | +Un point négatif est qu'il faut étendre toutes vos classes de bases |
| 40 | +(Activity, IntentService, AsyncTask, ...) en des classes venant de |
| 41 | +RoboGuice (RoboActivity, RoboIntentService, RoboAsyncTask, ...). |
| 42 | +L'intégration de RoboGuice avec d'autres frameworks ayant la mêle |
| 43 | +logique peut donc poser problème. |
| 44 | +Un point positif est que la version 2.0 est en beta 3 et se base sur |
| 45 | +Guice 3. Quoiqu'il en soit, ce framework mérite d'étre approfondi dans |
| 46 | +les prochaines semaines. |
| 47 | + |
| 48 | +### [Android Annotations](http://androidannotations.org/) |
| 49 | + |
| 50 | +Comme son nom l'indique, ce framework apporte un bon nombre d'annotations |
| 51 | +qui nous permettent d'éliminer beaucoup de code boilerplate. Un exemple |
| 52 | +valant mieux qu'un long discours : |
| 53 | +> @EActivity(R.layout.mon_activite) // content view => R.layout.mon_activite |
| 54 | +> public class MyActivity extends Activity { |
| 55 | +> @InjectView // Injection de R.id.titre |
| 56 | +> TextView titre; |
| 57 | +> @DrawableRes(R.drawable.logo) |
| 58 | +> Drawable logo; |
| 59 | +> @SystemService |
| 60 | +> SearchManager searchManager; |
| 61 | +> } |
| 62 | +
|
| 63 | +Le framework fonctionne par génération de code à la compilation (JAPT) en |
| 64 | +créant des classes suffixées d'un _. Une activity MyActivity devient donc |
| 65 | +MyActivity_ et doit être déclarée telle quelle dans le AndroidManifest.xml. |
| 66 | +Ce qui peut paraître au premier abord un gros point négatif apporte un |
| 67 | +avantage non négligeable : pas d'injection au runtime, le code généré |
| 68 | +ressemble beaucoup à du code Android "classique". De plus, Android |
| 69 | +Annotations a un footprint très léger : 50Ko. |
| 70 | + |
| 71 | +J'ai un vrai coup de coeur pour ce framework qui peut beaucoup nous aider |
| 72 | +au quotidien et permettre aux nouveaux développeurs Android de se concentrer |
| 73 | +sur le fonctionnel. Le développeur a même prévu une intégration avec |
| 74 | +RoboGuice, intégration qui sera étudié plus tard. |
| 75 | + |
| 76 | +### [Tiny Spring](http://code.google.com/p/tiny-spring/) |
| 77 | + |
| 78 | +Petit projet inspiré par le DI et IoC de Spring et prévu pour être dépoyé sur |
| 79 | +n'importe quelle plateforme. La définition des beans est faite en XML. |
| 80 | + |
| 81 | +Projet très jeune et peu documenté, pas du tout prêt à être utilisé. |
| 82 | + |
| 83 | + |
| 84 | +## ORM |
| 85 | + |
| 86 | +### [ORMLite Android](http://ormlite.com) |
| 87 | + |
| 88 | +ORM basé sur des annotations : |
| 89 | +> @DatabaseTable(tableName = "accounts") |
| 90 | +> public class Account { |
| 91 | +> @DatabaseField(id = true) |
| 92 | +> private String name; |
| 93 | +> |
| 94 | +> @DatabaseField(canBeNull = false) |
| 95 | +> private String password; |
| 96 | +> ... |
| 97 | +> Account() { |
| 98 | +> // all persisted classes must define a no-arg constructor with at least package visibility |
| 99 | +> } |
| 100 | +> ... |
| 101 | +> } |
| 102 | +
|
| 103 | +Il s'intègre bien dans les applications Android (l'API pour Android est là). |
| 104 | +L'intégration avec RoboGuice est possible et on obtient alors une stack qui |
| 105 | +s'approche du Spring + Hibernate côté serveur. On annote notre modèle, nos |
| 106 | +DAOs et nos services qui seront directement injectés dans nos activités. |
| 107 | +Ca fonctionne bien ensemble, reste à déterminer si les performances sont |
| 108 | +acceptables (Footprint de 274Ko). |
| 109 | + |
| 110 | +### [ActiveAndroid](http://www.activeandroid.com/) |
| 111 | + |
| 112 | +Encore un ORM basé sur les annotations mais payant (20$ USD). |
| 113 | +Inactif depuis le 12/2010... |
| 114 | + |
| 115 | +### [greenDAO](http://greendao-orm.com/) |
| 116 | + |
| 117 | +ORM léger et basé sur de la génération de code (encore un !). Cette génération |
| 118 | +est faite à la main (OPM sort de ce framework !). Le modèle est défini |
| 119 | +directement en Java (sans annotations). |
| 120 | + |
| 121 | +Ce framework se veut très rapide et léger mais il ne me donne aucune envie |
| 122 | +de le tester. Devoir générer le code à la main ainsi que décrire son modèle |
| 123 | +à coups de lignes Java ne me donne pas l'impression de m'aider dans mes |
| 124 | +développements. J'ai plutôt l'impression de revenir dans le temps. |
| 125 | + |
| 126 | +### [AndroidDataFramework](http://code.google.com/p/androiddataframework/) |
| 127 | + |
| 128 | +Framework espagnol, très peu documenté et en langue original. ORM très |
| 129 | +simple basé sur une définition du modèle en XML. A creuser un peu plus |
| 130 | +pour voir si il vaut le coup. |
| 131 | + |
| 132 | +### [db4o](http://www.db4o.com/android/) |
| 133 | + |
| 134 | +A étudier (Footprint de 1Mo...). |
| 135 | + |
| 136 | + |
| 137 | +## Presentation |
| 138 | + |
| 139 | +### [android-binding](http://code.google.com/p/android-binding/) |
| 140 | + |
| 141 | +Il s'agit d'un Model and View framework (MVVM à la WPF). |
| 142 | + |
| 143 | +Le model gère les données et les hanlders (on peut voir la déclaration de la |
| 144 | +Command AddContact qui est en fait un handler onClick directement "bindé" |
| 145 | +dans une vue XML avec binding:onClick="AddContact") : |
| 146 | +> public class ContactManagerModel { |
| 147 | +> private Activity mContext; |
| 148 | +> |
| 149 | +> public CursorSource<ContactRowModel> ContactList = new CursorSource<ContactRowModel> (ContactRowModel.class, new Factory()); |
| 150 | +> |
| 151 | +> public BooleanObservable ShowInvisible = new BooleanObservable(false); |
| 152 | +> |
| 153 | +> public Command PopulateList = new Command(){ |
| 154 | +> public void Invoke(View view, Object... args) { |
| 155 | +> populateContactList(); |
| 156 | +> } |
| 157 | +> }; |
| 158 | +> public Command AddContact = new Command(){ |
| 159 | +> public void Invoke(View view, Object... args) { |
| 160 | +> launchContactAdder(); |
| 161 | +> } |
| 162 | +> }; |
| 163 | +> |
| 164 | +> private void populateContactList() { |
| 165 | +> // Build adapter with contact entries |
| 166 | +> Cursor cursor = getContacts(); |
| 167 | +> ContactList.setCursor(cursor); |
| 168 | +> } |
| 169 | +> } |
| 170 | +
|
| 171 | +Les vues correspondent aux layout en xml avec des namespaces binding: (ce qui |
| 172 | +rend l'édition des vues xml incompatibles avec l'éditeur intégrér au plugin eclipse) : |
| 173 | +> <LinearLayout xmlns:android="http://...." xmlns:binding="http://www.gueei.com/android-binding/" ..> |
| 174 | +> <TextView binding:text="FirstName" ... |
| 175 | +
|
| 176 | +Les Activity android se chargent de faire le lien entre le modèle et la vue |
| 177 | +et absolument rien d'autre. Cela permet donc de bien séparer la partie |
| 178 | +présentation de la partie fonctionnelle. |
| 179 | + |
| 180 | +Le framework est très prometteur et permet d'effectuer de la validation de |
| 181 | +modèle à l'aide d'annotations sur les champs du modèle : |
| 182 | + |
| 183 | +> @Required(ErrorMessage="You must put the login name! (you can try Jean-Michel)") |
| 184 | +> public final Observable<CharSequence> Login; |
| 185 | +
|
| 186 | +ou encore : |
| 187 | + |
| 188 | +> @Required |
| 189 | +> @EqualsTo(Observable="Password") |
| 190 | +> public final Observable<CharSequence> ConfirmPassword; |
| 191 | +
|
| 192 | +Un framework à définitivement tester, ainsi que son intégration avec RoboGuice. |
| 193 | + |
| 194 | +### [Spring Android](http://static.springsource.org/spring-android/docs/1.0.x/reference/htmlsingle/) |
| 195 | + |
| 196 | +Il s'agit en fait de plusieurs modules de Spring pour le monde Android : |
| 197 | +* **RestTemplate** : un client REST très pratique qui nous permet de dialoguer en JSON / XML / RSS (footprint de 413Ko pour du JSON avec Google GSON par exemple) |
| 198 | +* **Android Auth** : facilite l'authentification via OAuth 1/2 (avec des modules spéciaux pour Twitter / Facebook via Spring Social) |
| 199 | + |
| 200 | +Un peu lourd en terme de taille de librairie mais nous facilite grandement la |
| 201 | +vie pour dialoguer avec des APIs REST. Android Annotations a d'ailleurs intégré |
| 202 | +RestTemplate dans ses annotations et ça devient vraiment sympa à coder. |
| 203 | +Il suffit de coder son service REST : |
| 204 | +> @Rest("http://monserveur.fr/api") |
| 205 | +> public interface MonServiceRest { |
| 206 | +> |
| 207 | +> @Get("/item/{id}") |
| 208 | +> @Accept(MediaType.APPLICATION_JSON) |
| 209 | +> Item getItem(long id); |
| 210 | +> } |
| 211 | +
|
| 212 | +Puis dans sa vue d'injecter le service et de l'utiliser ensuite : |
| 213 | + |
| 214 | +> @RestService |
| 215 | +> MonServiceRest monServiceRest; |
| 216 | +> |
| 217 | +> @AfterViews |
| 218 | +> @Background |
| 219 | +> void init() { |
| 220 | +> item = monServiceRest.getItem(2L); |
| 221 | +> if(item != null) { |
| 222 | +> showItem(); |
| 223 | +> } |
| 224 | +> } |
| 225 | +
|
| 226 | +En 10 lignes, j'ai codé un bout d'appli qui récupère directement mes données |
| 227 | +depuis mon serveur. A faire sans l'aide de framework, c'est beaucoup plus long |
| 228 | +et le bug est vite arrivé. A approfondir aussi ! |
| 229 | + |
| 230 | + |
| 231 | +## Outils |
| 232 | + |
| 233 | +### [Robolectric](http://pivotal.github.com/robolectric/) |
| 234 | + |
| 235 | +Framework de tests unitaires qui nous aiderait à faire du TDD. S'intègre avec |
| 236 | +RoboGuice. A tester (BFI avait commencé à l'utiliser sur un projet). |
| 237 | + |
| 238 | +### [Maven Android plugin](http://code.google.com/p/maven-android-plugin/) |
| 239 | + |
| 240 | +Permet d'utiliser Maven dans le cycle de vie de développement d'une application |
| 241 | +Android. Cela peut devenir pratique si on commence à utiliser beaucoup de librairies. |
| 242 | + |
| 243 | +Pour builder mon appli : |
| 244 | +> mvn install |
| 245 | +
|
| 246 | +Pour déployer l'application sur un terminal : |
| 247 | +> mvn android:deploy |
0 commit comments