Cet article retrace les sujets liés au développement Android et présentés lors de Droidcon de New York 2019.

Adaptation aux exigences de confidentialités avec Android 10 

Speaker : Nicole Borrelli

Permissions : pour plus de confidentialité et de compréhension de la part de l’utilisateur, le système de permissions a été découpé. Avant Android 10, on affichait la pop-up de permissions qui disait “Allow” or “Deny”. Maintenant, il pourra éventuellement avoir 3 choix : 

  • Allow all the time 
  • Allow only while using the app 
  • Deny

Il sera donc à la responsabilité du développeur de venir définir la nouvelle permission (d’accéder à la localisation même en background) dans le manifest, s’il en a le besoin.

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

External Storage : pour Android 9 et avant, il fallait une permission pour lire et écrire dans des fichiers. Avec l’arrivée d’Android 10, les permissions ne sont plus nécessaires pour accéder aux fichiers disponibles dans leur propre répertoire d’application. Cependant, des permissions sont toujours nécessaires pour accéder aux fichiers créés par d’autres. Les fichiers Photo, Video, Audio seront accessibles via MediaStore tandis que les téléchargements le seront via Storage Access Framework

Restrictions :

Les applications tierces ne pourront plus accéder à certaines informations telles que l’IMEI, le build serial. Il est donc préconisé de retirer tous les getDeviceId() des applications. Seul le système aura accès à ces informations. Dans le cas où cette méthode est laissée, une erreur du type SecurityException sera renvoyée. 

Il sera maintenant impossible pour une application de rentrer dans les paramètres pour venir activer ou désactiver le WiFi quand cela est souhaité. 

Best Practices :

  • Est-ce que mon application a vraiment besoin de ces informations ?
  • Avant d’appeler une API, est-ce que l’application a les permissions nécessaires ?
  • Comment se comporte l’application si l’utilisateur refuse les permissions ? 
  • L’utilisateur doit être averti de ce qu’il se passe en background de l’application

Getting to know Camera X

Speakers: Meghan Mehta & Oscar Wahltinez

Camera X est une librairie de support Jetpack pour rendre le développement d’application avec la caméra plus facile. Elle va permettre aux utilisateurs d’avoir exactement les mêmes expériences et mêmes fonctionnalités que l’application de caméra pré-installée sur le téléphone.

Pour cela, la nouvelle librairie s’est basée sur le package Camera 2, déjà existant. Cela a permis de revisiter le fonctionnement et de rendre le développement plus easy-to-use. Ces fonctionnalités permettent donc d’utiliser Camera X en réduisant considérablement les lignes de code lors de l’implémentation (environ 70% en moins).

Un grand avantage de cette librairie est la rétro-compatibilité jusqu’à Android 5.0 (API 21). Cela permet de la rendre accessible par un grand nombre d’appareils présents sur le marché. 

Un autre de ses avantages, comme dit plus haut, est son implémentation dans l’application. Pour cela, il suffit de lier les trois éléments suivant au cycle de vie, grâce à la méthode bindToLifeCycle

  • Preview : afficher une image sur l’écran et possibilité d’effectuer différentes action sur cette image : pincer pour zoomer, taper pour effectuer une mise au point.
  • Image Analysis : accéder aux informations de l’image.
  • Image Capture : enregistrer des images de haute qualité.

La librairie possède aussi une extension, optionnelle, qui permet de gérer différents modes tels que Portrait, HDR, Nuit ou Beauté (uniquement si ces modes sont déjà accessibles par les applications de caméra pré-installées). 

Attention, au moment du talk, la librairie était encore en Alpha car pas encore 100% finalisée. Il n’est donc pas recommandé de l’utiliser en production. 

Motion Layout

Speaker : Huyen Tue Dao

Sûrement l’un des talks qui m’a le plus captivé, tant par la passion de l’intervenante pour son sujet que par mon affection pour le visuel. En effet, en tant que développeur mobile, la partie design et la mise en place de celui-ci, est une partie que j’affectionne beaucoup et qui est très importante à mes yeux. C’est le petit côté sexy que je trouve au développement et c’est souvent un nouveau challenge pour mettre en place les designs pensés par les équipes dédiées.

Depuis quelques mois, le layout le plus utilisé et le plus aimé des développeurs Android est le ConstraintLayout. Il simplifie énormément de codes dans les fichiers .xml, évite toutes les imbrications et étages qui pouvaient exister avant. 

MotionLayout est le dernier layout introduit par ConstraintLayout. Il permet de fournir des animations et des transitions très recherchées. L’ensemble des animations et transitions déjà utilisées avec Android peuvent être faites plus clairement et facilement à l’aide de MotionLayout. 

Au cours de ce talk, nous avons pu assister à une démonstration live d’animation qui transformait l’ancien design de droid en son nouveau. Petit clin d’oeil ici à l’annonce d’Android 10, faite quelques jours plus tôt, qui avait beaucoup fait parler avec toutes ses modifications: changement de couleur, de forme, de nom … qui pour la première fois n’était pas un nom de gâteau.

Beaucoup de notions ont été rapidement abordées:

  • MotionScene : fichier xml qui est contenu dans le nouveau package de ressources xml qui va servir comme description pour dire toutes les transitions et contraintes qui seront appliquées à la scène.
  • Transition : va définir les mouvements appliqués aux éléments grâce à un déclencheur (exemples de trigger : OnSwipe, OnClick, etc…). En 3 lignes maximum, il est possible de donner toutes les informations nécessaires au trigger : quel élément va servir d’ancre ou de cible, quelle direction agit comme trigger, où l’ancre se situe dans la scène avant le déclenchement, quelle transition sera lancée au clic sur la cible . 
<OnClick 
	motion:targetId="@+id/button" 
	motion:clickAction="transitionToEnd"/>
<OnSwipe
	motion:dragDirection="dragUp"
	motion:touchAnchorId="@+id/image"
	motion:touchAnchorSide="top"/>
 
  • ConstraintSet: pour aller un peu plus loin avec les transitions il est possible de définir des états. On pourra ensuite donner ces états au transition pour lui dire : au départ tu seras dans l’état A et à l’arrivée dans l’état B. 
  • Constraint: quand on définit un état, on peut lier une contrainte spécifique à un id (une sorte d’ancrage). Grâce à cette ancre, on peut appliquer à cet élément des variations très simplement à l’aide d’une CustomAttribute.
<Constraint
    android:id="@+id/button" ...>
    <CustomAttribute
        motion:attributeName="colorFilter"
        motion:customColorValue="#D81B60"/>
</Constraint>
  • KeyFrameSet: dans certaines situations, en plus des états de repos définis à l’aide des ConstraintSet, un état intermédiaire, par lequel on ne fait que passer, peut être désiré. Un KeyFrame peut être appliqué selon une position ou une valeur attribuée spécifiquement.
  • KeyPosition: il suffit de donner la cible, la valeur de modification et la position (framePosition) à laquelle l’état intermédiaire devra se produire.
<KeyFrameSet>
     <KeyPosition
         motion:keyPositionType="parentRelative"
         motion:percentY="0.25"
         motion:framePosition="50"
         motion:target="@+id/button"/>
</KeyFrameSet>
  • KeyAttribute: sur le même fonctionnement que KeyPosition, il est possible de donner plus de changements à la cible. Par exemple, jouer sur sa rotation ou son échelle au moment de l’état intermédiaire.
<KeyFrameSet>
    <KeyAttribute
        android:scaleX="2"
        android:scaleY="2"
        android:rotation="-45"
        motion:framePosition="50"
        motion:target="@id/button" />
</KeyFrameSet>
  • KeyCycle: moyen très détaillé et personnalisable à souhait pour créer une vue très spécifique. Nous pouvons mettre ça en parallèle avec une courbe que l’on vient customiser et faire des répétitions : nombre de vagues, forme de la vague, animations à jouer, position initiale.
<KeyFrameSet>
<KeyCycle 
        motion:framePosition="0"
        motion:target="@+id/button"
        motion:wavePeriod="0"
        motion:waveOffset="0"
        motion:waveShape="sin"
        android:rotation="0"/>

<KeyCycle 
        motion:framePosition="50"
        motion:target="@+id/button"
        motion:wavePeriod="1"
        motion:waveOffset="0"
        motion:waveShape="sin"
        android:rotation="20"/>

<KeyCycle 
        motion:framePosition="75"
        motion:target="@+id/button"
        motion:wavePeriod="3"
        motion:waveOffset="0"
        motion:waveShape="sin"
        android:rotation="20"/>

<KeyCycle 
        motion:framePosition="100"
        motion:target="@+id/button"
        motion:wavePeriod="0"
        motion:waveOffset="0"
        motion:waveShape="sin"
        android:rotation="0"/>
</KeyFrameSet>
  • ConstraintTag: souvent la target est l’id d’un élément spécifique. Il est possible d’associer à chaque élément un ConstraintTag et de venir choisir comme target un groupe de constraintTag (exemple: motion:target=”tag.*”)

Petit tip de la présentation : showPaths = true !!! Paramètre très utile en DEBUG qui va afficher dans la preview d’Android Studio des flèches matérialisant les différents déplacements qui seront effectués par les différents éléments de la vue.

La conférencière nous a montré qu’avec le MotionLayout et la notion de progression, distance entre les éléments, elle était capable de faire comme un CoordinatorLayout avec des variations supplémentaires. Son exemple était le suivant: lors de l’effet parallax, elle faisait bouger un Floating Action Button (FAB) d’un point A à un point B et pendant ce déplacement, le FAB changeait de couleur, d’image et de forme en subissant une rotation.

Huyen a insisté sur le fait qu’il ne faut pas voir le MotionLayout comme un Layout qui doit être mis en place impérativement mais plus comme une chose qui peut être ajoutée à l’actuel pour rendre les choses plus belles et plus faciles.

Make better decisions

Speaker: Kate Kelly

Experimentation is different from A/B testing

Sa citation a été expliquée de la façon suivante : lors d’un A/B testing, le but est de définir laquelle des deux méthodes est la meilleure. Lors d’une expérimentation, on émet des hypothèses et l’on va venir se servir d’A/B testing pour essayer de trouver des réponses.

Pour expérimenter, il faut tout d’abord mettre en place une hypothèse.
Pour cela, il faut définir une conduite de base où l’utilisateur n’aura pas de changement puis une variante, là où il y aura le changement et qu’il faudra venir analyser par la suite (à l’aide d’un A/B testing).

Dans son étude de cas, l’hypothèse de départ était que le scroll infini sur l’application pouvait repousser les utilisateurs à aller plus loin et donc ralentir l’achat. Deux tests ont donc été définis :

  • Test A : afficher plus d’items sur une page.
  • Test B : avoir un chargement plus rapide.

Le résultat … aucun des deux tests n’a permis d’accroître l’achat. Donc l’hypothèse n’étant pas validée, malgré l’A/B testing, aucune solution ne sera retenue. 

Et si un test était ressorti majoritaire, comment savoir s’il ne s’agit pas d’une chance ou d’un réel choix ou d’un soucis dans le panel. Pour remédier à ça chez Etsy, ils ont mis plusieurs choses en place: 

  • Au lieu de tester 50% A et 50% B comme souvent, ils sont partis sur 5% le variant et 95% le contrôlé.
  • Pour éviter le soucis du panel, ils se basent sur le fonctionnement des features flags et se servent des SharedPreferences de l’application pour gérer les deux versions.
  • Tout est potentiellement A/B testable mais ils partent du principe qu’il est étrange de vouloir effectuer un A/B test sur certains éléments/changements (arrivée de Material design, nouveau fonctionnement de navigation, etc.)
  • Ne pas regarder le résultat trop rapidement. Laisser le temps au test de réellement parler et ne pas laisser un pic (hasard) dicter le résultat du test.

Il ne s’agit là que d’un retour d’expérience pour un projet spécifique. Ce sont des conseils par rapport à un retour d’expérience, il faut toujours faire preuve d’adaptabilité en fonction de son projet.

Using Machine Learning to make your UI tests more robust

Speaker : Godfrey Nolan

Les tests, beaucoup de tests unitaires sont écrits mais très peu de tests UI. Pourquoi ? Parce qu’ils sont fragiles. Un tout petit élément modifié et cela peut faire échouer le test. Autrement dit, consacrer beaucoup de temps pour maintenir ces tests. 

Et si une solution pour ces tests était d’utiliser le Machine Learning pour les effectuer ? 

En effet, beaucoup d’écrans d’application se composent d’éléments communs : bouton recherche, barre de recherche, burger bouton, panier, etc.

Le speaker nous a montré comment à partir de Test.ai Classifier Plugin il était possible d’écrire rapidement un test UI et que celui-ci pouvait être joué sur différentes applications.

Il s’agit d’un plugin d’expérimentation pour Appium qui utilise le classificateur de type d’éléments du Machine Learning de Test.ai (pour les passionnés d’Intelligence Artificielle, articles très intéressants sur ce blog en lien avec les tests). Cette façon de faire permet de retrouver des éléments grâce à une sémantique (“cart”, “microphone”, “arrow”, “next”) plutôt que devoir se baser sur l’architecture entière de l’application. 

Flutter at scale

Speaker : Jorge Coca

Finalement, il s’agira de la seule conférence sur Flutter à laquelle j’ai pu assister. De base, il n’y en avait pas énormément et puis après il y a toujours des choix à faire. 

Conférence en demi-teinte pour ma part. Il s’agit d’un retour d’expérience de l’intervenant pour son projet, pas de code, juste comment ils utilisaient Flutter dans leur projet. N’ayant que très peu de notions sur Flutter : j’ai assisté à la formation d’Ineat Academy mais dans ma mission actuelle je n’ai pas encore l’opportunité de pratiquer.

La problématique de la conférence était la suivante : est-ce que Flutter est prêt pour être utilisé à (grande) échelle ? 
Grâce à son expérience, la réponse est un grand …. OUI (sans grande surprise). 

Voilà les raisons qu’il a énumérées: 

  • Développement évolutif : pas besoin de tout migrer d’un coup, petit à petit.
  • Développement facile : le côté évolutif rend le développement facile à prendre en main.
  • Performant : au niveau des animations, transitions un seul chiffre 60 pour 60 FPS (frame per second). 
  • Expérience sécurisée : pas trop de risques à mettre Flutter en place dans le projet.
  • Déploiement continu : nécessaire pour son projet et 100% réalisable avec Flutter.

Liste des outils utilisés sur ses projets : 

  • Haut niveau d’architecture : modules verticaux (data, domain, UI & State) et horizontaux (feature, composition).
  • Flutter bloc : package flutter pour aider à l’implémentation du pattern BLoC (Business Logic Component) qui fonctionne principalement avec des Streams.
  • Lumberdash : c’est leur solution pour les logs. Une puissante API grâce à laquelle il est possible d’enregistrer facilement les logs. Il est aussi possible de customiser des plugins pour des besoins spécifiques. Fonctionne très bien avec le client Firebase.
  • Ozzie : solution créée par BMW pour les tests et disponible dans la liste des packages sur le site officiel. Ozzie a une option qui permet de prendre un screenshot pendant les tests d’intégration à n’importe quel moment. Il va aussi faire des rapports de performances et les enregistrer.

Série d’articles