Android à Devoxx (BE) 2013 - Le Compte Rendu

J'ai eu à nouveau le plaisir cette année de participer à Devoxx, et j'en reviens plein de petits robots verts dans les yeux.

Devoxx est l'une des plus grosse conférence Java en Europe et se déroule chaque année à Anvers (Belgique). Depuis peu Devoxx s'est aussi étendu en France et au Royaume Uni. Mais ce compte rendu couvre bien la version originale.

Cette année j'ai participé presque essentiellement à des sessions sur divers aspects d'Android, et voici le résumé de celles-ci.

Attention : Le compte-rendu est long et souvent technique, car il y avait quand même 3 jours et beaucoup de contenu, parfois relativement en profondeur.

DAY 1

What’s new in Android KitKat? - Romain Guy + Chet Haase (Google)

Les nouveautés de KitKat ont déjà été pas mal discutées un peu partout, mais il y a tout de même quelques trucs qui en ressortent que je trouve particulièrement intéressantes :

  • Les webviews sont maintenant basées sur Chromium. Cela signifie 2 choses en particulier : la première est que maintenant les webviews ont maintenant la même puissance de rendition que Chrome; la seconde est que maintenant il est possible de débugger le contenu d’une webview à partir de chrome sur l'ordinateur en utilisant les mêmes outils que l’on utilises pour débugger / analyser une page web normale. Cela se fait en utilisant l'URL chrome://inspect directement dans chrome, lorsque le périphérique est branché en USB sur la machine.

  • Le Storage Access Framework qui permet un accès aux fichiers internes de manière unifiée dans toutes les apps. Cela signifie que maintenant, toute applications utilisant cette API pourras demander l'accès à une ressources se trouvant sur diverses sources automatiquement. Ces sources sont soit le stockage interne (les images, les downloads, etc), Google Drive, etc. De plus n'importe quelle application peut ajouter son propre provider pour cette interface rendant le Framework très flexible.

  • Le Printing Framework  permettant d'imprimer des documents directement à partir de votre device. Pour le moment KitKat vient dès le départ avec un plugin pour Google Cloud Print ainsi qu'un plugin permettant de se connecter sur les imprimantes HP compatibles. Techniquement, la méthode pour imprimer un document avec ce Framework est de générer et d'envoyer du PDF vers l'imprimante, de ce fait une API permettant de gérer ce format est mise à disposition, incluant notamment la classe PrintHelper permettant de facilité le travail.

  • Visuellement, les modes plein écrans ont été agrémentés d'un mode immersif. Concrètement le mode immersif va faire disparaitre la barre de notification et la barre de navigation (pour les modèles qui l'affichent) permettant à l'application d'utiliser absolument tout l'écran. L'utilisateur peut alors faire revenir ces barres en les "tirant" du haut de l'écran. Ajoutez à cela la possibilité de mettre un effet transparent sur ces mêmes éléments du système, permettant de rendre votre application vraiment très profondément intégrée sur l'écran. Voir ici pour plus de détails.

  • L’ajout de scènes et de transitions, permettant d’ajouter pas mal de mouvement et d'animation dans une même activité. Nottament nous pourrions imaginer avec une application avec une seule activité dont les différentes fonctionalités seraient mise en scène utilisant ces principes de scènes et de transitions. Cette vidéo explicative sera certainement une bonne source pour bien comprendre le principe.

  • Mode auto-miroir pour permettre d’adapter le mode de lecture gauche à droite automatiquement dans les applications. Maintenant il est possible d'utiliser ce mode avec n'importe quelle langue, ce qui est pratique pendant le mode de développement si l'on ne parle pas un langage de ce type. Plus de détails ici.

  • Certaines des améliorations syntaxiques de Java 7 sont maintenant disponibles pour le développement d'applications Android (opérateur en diamant, multi-catch, etc), pour le moment uniquement par le biais de l'IDE Android Studio. Attention, certaines ne sont disponibles que si le sdk minimum de l’application est KitKat (19). Plus d'information sur cet article.

  • Le nouvel SDK nous apporte un utilitaire permettant d’enregistrer au format vidéo ce qui se passe sur l’écran, très pratique pour faire des vidéos de démo ou promotionnelles. Je pense que cet outil deviendra très vite quelque chose dont on ne peut pas se passer. Cet utilitaire peut être lancé en ligne de commande ou bien directement dans Android Studio.

  • ART (Android RunTime), qui est une nouvelle VM qui va, à terme, remplacer Dalvik. Pour le moment il s'agit uniquement d'une option se trouvant dans le menu développeurs, et elle n'est pas encore prête pour le prime time. La différence entre les 2 technologies est le type de compilation. Dalvik se base maintenant sur le principe JIT (Just In Time), ART quant à lui se base sur une méthode AOT (Ahead Of Time), ce qui théoriquement va améliorer les performance. Note : je n’ai personnellement pas eu la patience d’attendre la mise à jour sur mon Nexus 4 et ai donc installé l’image d’usine, j’ai directement mis ART comme VM principale … je ne vois absolument aucune différence jusque maintenant, excepté sur quelques applications, dont Timely, qui prend un peu plus de temps pour démarrer.

Tout ceci est extrèmement résumé, mais cela donne déjà une idée. Il y a encore beaucoup d'autres nouveautés dans cette nouvelle version du système Android, et je vous invite à les décrouvrir toutes plus en détails sur la page officielle.

Toutes les slides des sessions de Romain Guy et Chet Haase sont disponible sur DropBox, et les slides de cette session en particulier sont disponibles aussi sur SlideShare.

Mastering Android Drawables - Cyril Mottier (Capitaine Train)

Tout ce que vous avez toujours voulu savoir sur les Drawables sous Android. L’idée de la session était de redonner un peu de vie aux drawables qui sont relativement sous ou mal utilisés.

Les drawables se caractérisent comme étant un objet qui a des limites (bounds), un niveau (level), un état (state). Mais en fait c’est plus que ça : c’est une classe abstraite qui peut être étendue.

L’état du contenu d’un drawable (Content State) est le même pour toutes les instances du drawable. Qu'est-ce que cela veut dire ? --> Lorsque l'on exécute 2 fois la méthode getDrawable(R.drawable.myDrawable), nous obtenons 2 instances différents. Mais alors ça veut dire que l'image est chargée 2 fois en mémoire ? Cela doit être abominable pour les performances non ? Et bien en fait non, il se fait que le Constant State de chacun des drawables est le même. C'est bon à savoir.

Dans le cas ou l’on a besoin d'avoir un Content State différent pour plusieurs drawables pointant vers la même ressource, il existe une méthode mutate() qui elle va faire une copie de l’état.

L’utilisation des drawables va aider à réduire la profondeur de la hérarchie des vues. En effet, il est très intéressant d’un point de vue des performances de retirer tout ce qui est inutile dans un layout et de le remplacer par des drawables.

Par exemple, on peut utiliser un Layer List drawable pour dessiner la couleur du fond de l’écran et un logo / une image qui s'affiche au centre de l’écran. Cela permet à une meilleure expérience utilisateur (l’image apparait directement, avant que le layout soit interprété), et une meilleure performance (le drawable n’est affiché qu’une seule fois alors qu’un layout complexe peut lui être interprété plusieurs fois).

Note : contrairement aux views, les drawables ne peuvent pas avoir des tags customisés en XML.

Pour plus de détails sur cette présentation, je vous invite à visionner les slides.

Efficient Image Processing on Android - Nicolas Roard (Google)

Cette session était très technique. Le fil conducteur était le nouvel éditeur photo d’Android KitKat.

La première chose était l’explication de la technologie utilisée derrière et pourquoi.

Quatre choix étaient disponibles :

  • Java (Android SDK), mais pas retenu, trop de GC, pas suffisamment rapide … c’est probablement suffisant pour faire du prototyping mais sans plus.
  • OpenGL, solution rapide mais difficile d’assurer les performances des shaders, la taille du buffer est limitée, et c’est difficile et coûteux de récupérer les images modifiées.
  • NDK (Native Development Kit), code native en C/C++ à la Google, pas trop mal et facile à manipuler mais il était trop compliqué de gérer plusieurs architectures (trop bas niveau).
  • RenderScript, solution retenue car le code est clair, ça prend moins de place, reprend toutes les bonnes choses de Java, très portable car les scripts tournent en parrallèle sur le CPU et le GPU (bien que pour l’utilisation du RenderScript sur GPU, il est nécessaire d’avoir les drivers adéquat … garantit avec les périphériques Nexus, potentiellement pas présent sur d’autres marques mais tout de même très répandu).

De plus les scripts peuvent être appelés à partir du code Java ou du code natif, et disponible dans la librairie de comptabilité (et donc compatible jusque Android 2.2). En bonus, le résultat est beaucoup plus rapide que les autres solutions.

Pour toutes ces raisons, la solution RenderScript était la meilleure pour le besoin.

Il a bien entendu partagé un petit les slides de sa présentation. Je vous les recommandes si ce sujet vous intéresse.

Awesome Android Design - Nick Butcher (Google)

Nick Butcher est un personnage récurent dans la série de vidéos Android Design In Action.

Sa session à Devoxx était en gros le même contenu que cette vidéo “New in Android 4.4” mais voici les highlights.

Premièrement : un clin d’oeil de sa part à ce merveilleux outil qu’est Android Holo Colors ce qui fera certainement plaisir à son créateur (Jérôme Van Der Linden, architecte mobile chez OCTO).

A retenir :

  • Holo grandit et mature, ce langage visuel prend une tournure Content First Approach. On maximise l’accent sur le contenu, et on réduit au minimum le bruit visuel → boutons sans bords, overlays d’informations sur les images par exemple, etc.
  • Roboto aussi s’améliore, et offre plus de formats. Ceci permet d’utiliser cette typographie afin de fournir une structure et de l’emphase dans les messages et le contenu.
  • Holo n’est pas juste une couleur (le fameux bleu #33b5e5), mais bien un langage visuel. La couleur est utilisée pour faire ressortir les fonctionnalités. → Utilisation de Android Holo Colors !
  • Ne pas réinventer la roue, il faut utiliser le framework, réutiliser les styles existants, et les adapters / les étendres si besoin, afin d’assurer une omogénéité de UX parmis les apps Android.
  • Le Responsive Design est de mise aussi sur Android. Il est important de penser un design qui s’adapte sur plusieurs tailles d’écrans dès le départ sur Android, one app does it all.

Pour cela, il faut combiner le contenu afin que cela s’affiche au mieux sur chaque écrans, utiliser les fragments, etc … rien de nouveau de ce côté.

Quelques exemples de techniques :

  • Utiliser le SlidingPaneLayout par exemple pour avoir un maximum d’informations sur un plus petit écran, tout en gardant une structure de layout similaire quel que soit le format du périphérique.

  • Externaliser les valeurs et les dimensions en les mettant dans des répertoires de resources. Ces répertoires peuvent-être spécifique pour une taille ou un format d’écran ce qui permet un maximum de réutilisation malgré les résolutions multiple.

Quelques autres conseils :

  • Utiliser des largeurs maximum (layout_maxwidth paramètre dans le layout) : il faut éviter les textes immenses qui prennent tous l’écran, surtout lorsqu'il s’agit d’une tablette 10 pouces en mode landscape. La mesure optimale pour le texte est entre 45 et 75 caractères par lignes.

  • Mieux vaut couper une image afin de la montrer dans un layout complexe (exemple : un écran de départ affichant des articles avec une photo) pour être sûr que l’expérience sera toujours la même quel que soit le format de l’écran. L’image pourra alors être affichée au complet sur l’écran spécifique à l’affichage de l’article par exemple.

Dans l’ensemble une session très intéressante, mais encore une fois très semblable à ce qui se dit dans les vidéos citées ci-dessus.

DAY 2

Create Filthy Rich Apps on Android - Romain Guy + Chet Haase (Google)

Encore une session par les 2 compères Android que tout le monde aime. Il s’agit d’une adaptation de leur livre "Filthy Rich Clients" écrit en 2007  contenant des trucs et astuces pour rendre une application Swing vraiment attrayante, mais pour le monde Android.

La session était vraiment pleine d’informations, à tel point qu’encore une fois je vais plutôt vous proposer d'aller voir les slides plutôt que d’essayer de décrire tout ce qui s'est dit et risquer de faire trop d'erreurs.

A retenir : Il est préférable d'utiliser des shaders pour obtenir la meilleure optimisation possible. La définition exacte d’un shader par les 2 comparses : shader = "a set of instructions that compute the source color of a pixel bing drawn".

Voir la page JavaDoc sur la classe Shader du SDK pour plus d’informations.

Exemples de shaders :

  • Painter.setColor = le plus simple des shaders qui existe

  • BitmapShader = très simple à utiliser, très efficace avec le tile mode Clamp.

  • ComposeShader = prend 2 shaders et les mélange ensemble.

Quelques recommendations :

  • Lorsque l’on veut animer une ListView, faire bien attention à animer l’élément de la liste, et non toute la vue. Je vous conseille cette vidéo pour une jolie explication de cette technique.

  • Il est possible d’utiliser des animations et des shaders en même temps → il suffit de créer un shader puis d’animer ses propriétés en utilisant un ObjectAnimator ou AnimatorSet.

  • Pour les transitions d’activités personnalisées, il est préférable de désactiver les “window animations”. Il faut le faire dans l’activité, démarrer une nouvelle activité avec fond transparent et animer le contenu une fois que l’activité est mise en place.

Il y en a bien d’autres, vraiment allez voir les slides et / ou attendez la vidéo sur Parleys.

Build an Android App with Dagger - Jake Wharton (Square)

Je connais un peu du travail de Jake Wharton sur Android, et je pense que bon nombre de développeurs Android aujourd'hui le connait égallement → il s'agit de l’homme qui est derrière ActionBarSherlock permettant aux applications d'incorporer l'ActionBar d'Android pour les périphériques tournant sur une version antérieur à 4.0 d'Android.

Dans cette session néanmoins, il est venu nous parler d’un autre projet. Celui-ci réalisé sous l'ombrelle de Square, qui s'appelle Dagger. Il s’agit d’un système d’injection de dépendances, qui est disponible en Open Source sur github

Vous allez me dire "encore un ?". Oui en effet, vous connaissez peut-être déjà RoboGuice ou bien Guice … mais Google nous suggère de ne PAS les utiliser (voir la section "Avoid dependency injection frameworks" de cette page). La raison : il s’agit d’une exécution au runtime, ou le framework va faire du scanning d’annotations ce qui va prendre pas mal de mémoire, et beaucoup impacter les performances et l'expérience de l'utilisateur de l'application.

Dagger quand à lui n’est pas une librairie effectuant l'injection au RunTime. Au contraire, Dagger crée du bytecode à la compilation permettant ces injections.

Quelques avantages :

  • Utilisation de l’ObjectGraph, un mapper d’instances et de points d’injections.

  • Fail Fast : en cas de problèmes syntaxique ou autre, le problème apparait à la compilation et non au runtime.

  • Pas de Reflection

  • Pas d’impact sur la mémoire.

ObjectGraph est un graph de directives acycliques. En anglais : "Directive Acyclic Graph" = DAG-ger. Voici d’où vient le nom.

Le principe est simple :

  • D’un côté nous avons l’ObjectGraph qui est le manager central des dépendances, et injecteur. La classe peut être étendue pour créer des scopes. L’objet est immutable, et se construit en général dans l’instance d’Application de votre app.

  • D’un autre côté nous avons les Modules, qui sont en gros des factory qui disent à Dagger comment créer les instances.

  • Dans le 3ème coin nous avons les Providers qui indiquent le type de retour d’un module.

  • Et enfin nous avons l’annotation @Inject qui va exécuter l’injection. L’injection peut se faire dans le constructeur, ou directement sur les variables.

Le seul bémol est qu’il faut lister les points d’injection dans chaque module afin de permettre l’analyse statique dont Dagger à besoin. C’est essentiellement utile pour la compilation incrémentale.

Tester un système d'injection de dépendances n'est pas chose aisée, c'est pourquoi Dagger est mockable grâce à un mode de mock prévu dans la librairie, mais aussi un "debug drawer" c'est à dire un et diverses méthodes afin de facilité le test.

En cadeau, Jake nous a promis de mettre à disposition très bientôt une application d’example, qui s’appelle u2020, mettant en place toutes les meilleures pratiques de code pour Dagger, mais aussi d'autres de leur librairies.

Attention : Dagger n’est pas encore prêt pour Proguard, mais ils y travaillent.

Quelques tips de ce qu’il ne faut PAS faire avec l’injection de dépendances :

  • ne PAS ignorer le pattern

  • ne PAS injecter tout et n’importe quoi dans tous les sens, le faire uniquement quand ça apporte quelque chose.

  • ne PAS mettre les dépendances dans des champs statiques.

Dans l’ensemble, mon sentiment est qu’il y a beaucoup de potentiel et ça me donne envie d’essayer.

Toutes les librairies pour Android de SquareUp sont toujours très utiles et très bien réalisées, je ne vois pas pourquoi celle ci serait différent. Donc pour plus d’infos, voir le site et le github.

En bonus, une petite photo de Jake pendant sa session (il nous a demander d’en faire et de les posters sur G+)

Riddle me This, Android puzzlers - Richard Hyndman + Stephan Linzner (Google)

Cette session était sous forme de questions / réponses sur la technologie Android afin de dévoiler certaines des pratiques problématiques qui reviennent souvent.

En vrac :

  • Le ContentProvider est le premier élément à être instancié

  • Il faut utiliser ArrayMap pour économiser la mémoire, SparseArray / LongSparseArray pour éviter le unboxing, plus efficace en mémoire et disponible dans la librairie de support

  • Lorsque l’on utilise des SharedPreference, il faut faire attention au multi-process. Il faut essayer de garder les classes utilisant ces préférences dans le même process.

  • C’est plus efficace de faire intent.get<Type>Extra(Key) plutôt que intent.getExtras().get<Type>(Key) car la méthode getExtras() va systématiquement créer une copie du bundle.

  • Il est préférable d’utiliser un WakefulBroadcastReceiver pour réveiller un service pour améliorer le temps de réponse et de communication, aussi garder le broadcaster et le service dans le même process.

  • Il existe un outil de stress test sur Android qui s’appelle Monkey Tool. Néanmoins, il est parfois préférable de ne pas laisser le système de stress test exécuter certaines actions dans l’application pour quelque raison que ce soit. Pour ce faire, il suffit d’utiliser la méthode ActivityManager.isUserMonkey() afin de prévoir un cas particulier dans le cas d’un stress test de Monkey Tool.

  • Utiliser le moins de permissions possible afin de ne pas effrayer l’utilisateur. Par exemple, utiliser l’intent ACTION_DIAL pour appeler un numéro de téléphone, pareil pour les contacts, etc. En d’autres termes : utilisez le framework autant que possible, lisez la doc.

  • Un LinearLayout horizontal prend plus de temps à être rendu qu’en vertical parce qu’il essaye de faire un basealign sur tout les composants, et donc risque de faire plusieurs passes.

  • Une démo du mode débug des nouvelles webview avec chrome://inspect.

Difficile d’en dire plus dans un compte rendu, une seule adresse si vous voulez plus d’informations là-dessus : Parleys !

DAY 3, The Final Day

Gradle for Android and the Rest of the World - Hans Dockter (Gradleware)

C’est toujours bien d’avoir un fondateur / inventeur parler de son bébé. Dans ce cas, c’était le papa de Gradle qui est venu nous montrer la puissance du plugin Android pour Gradle.

En résumé, il a mis l’accent sur le fait que Gradle était très déclaratif et personnalisable, et c’est grâce à cela que l’utilisation de cet outil pour Android est une bonne solution.

La sessions incluait beaucoup de live coding et de démo pour démontrer la simplicité du système, notamment pour les flavors, les build types, les groupes, etc.

Pour ceux qui ne connaissent pas Gradle, je vous conseil ce point de départ, et pour ceux qui ne connaissent pas les spécificités Android, et bien cette page et celle ci aussi devraient vous aider à en apprendre plus.

Bonus : Introduction to Google Glass - Alain Regnier (Alto Labs)

Nous avons eu droit à une heure de présentation de Google Glass, son utilisation, comment ça marche, à quoi ça sert, et comment on fait des applications.

Je ne vais pas refaire la présentation complète des Google Glass, il y aurait beaucoup trop à dire. Ce qui m’intéressait essentiellement est la réalisation d'applications.

Pour créer une application pour Google Glass, d'abord il y avait l'API Mirror. En effet il nous a expliquer le principe :

  • D’abord faire une app sur Google App Engine

  • Activer le service Google Glass dans les API Google, qui n’est disponible que pour les gens faisant partie du programme Google Glass Explorer.

  • Utiliser le Mirror API sur le front-end de l’app, qui est fait en JSP / HTML, afin de récupérer des informations et de pouvoir les afficher sur Glass.

En très résumé c’est à peu près tout, c’est relativement limité (pas d’accès aux capteurs, pas énormément de possibilités autre que de l’affichage de contenu, limite de 1000 requêtes API par jours).

Il nous a prévenu que la sortie du Glass Development Toolkit allait bientôt être annoncé, et c’est maintenant chose faite. Le GDK permettra d’écrire des applications Android et de les installer directement sur Glass, et donne accès à beaucoup plus de fonctionnalités que les applications web disponible jusque là --> accès aux capteurs internes, créations de cartes "Google Now", détection de gestures, etc.

Session intéressante donc pour Google Glass, mais rien de très neuf pour ceux qui suivent un peu le sujet.

Et ceci conclu mon séjour à Devoxx cette année.

Merci de votre lecture.