Android Makers by Droidcon 2024 - Partie 2 : same, same but (also) different

Si vous avez apprécié notre premier article sur l'Android Makers 2024, voici donc le second et dernier pour vous faire profiter des talks qu'on a le plus aimés.

Kotlin multiplatform at stable and beyond

Márton Braun - Developer Advocate @ JetBrains - Ses slides

Kotlin Multiplatform (KM) a énormément évolué depuis son apparition en alpha en 2020. C’est exactement ce que Márton nous décrit dans son talk en retraçant de manière globale l’historique de KM jusqu’à la parution de la version stable en Novembre 2023.

Mais une piqûre de rappel ne fait jamais de mal : qu’est-ce que Kotlin Multiplatform ? KM est tout simplement un framework permettant de développer des applications en Kotlin sur une multitude de différents supports : Web, Desktop (Windows/MacOS, Linux) et Mobile (Android/iOS). Sa particularité tient du fait qu’il produit du code natif et ne permet à l’origine que de mutualiser tout le code dit “métier”, laissant l’implémentation de l’interface graphique à la charge de la cible (mobile / web / etc). Jetbrains, créateur et mainteneur principal de KM, offre ainsi la possibilité de profiter de la fraîcheur du langage Kotlin pour éditer toutes sortes d’applications.

Márton nous rappelle ainsi comment fonctionne KM : un module Common permettant de stocker le code commun et des modules cibles tels qu’iOS, Android ou encore Desktop, le tout écrit en Kotlin !


Il reste alors les cibles finales, typiquement sur mobile, un projet gradle pour android et un XCProject pour iOS, qui peuvent contenir du code natif à chaque OS et qui permet de définir l’interface graphique.

D’ailleurs, une fois le fonctionnement basique de KM expliqué, Márton nous parle également de l’écosystème Multiplatform et du tooling associé. Et sans surprise, Compose Multiplatform (CM) est abordé en premier. Ce framework est justement la solution presque officielle pour pallier ce souci d’implémentation séparée pour l’UI. Basé sur le framework Jetpack Compose créé par Google pour construire l’UI Android, CM est une surcouche portant les APIS Compose sur les différentes plateformes Desktop, iOS, etc.


CM est seulement en alpha ou même en expérimental côté Web, mais cela a l’air prometteur. Il serait intéressant de comparer les performances de KM + CM face aux deux frameworks hybrides que sont React Native et Flutter. Peut-être un nouveau concurrent pour lequel les entreprises vont devoir prendre en compte ?

Márton enchaîne ensuite sur l’augmentation certaines des bibliothèques dédiées à Kotlin Multiplatform. Il en profite pour présenter des releases très inspirées de l’éco-système Android mais pensées pour KM : les bibliothèques ViewModel et Lifecycle. La première permet de définir un standard pour l’implémentation du pattern MVVM en fournissant un objet “ViewModel” similaire à ce qui se fait sur Android, objet géré par un Store et pouvant être combiné à un cycle de vie. Lifecycle justement permet d’avoir une abstraction du cycle de vie d’un composant (Fragment / Activity / Compose Component) et ce sur toutes les plateformes cibles afin de pouvoir gérer plus efficacement la communication entre le métier et l’UI. Deux bibliothèques qui nous semblent très intéressantes à essayer, surtout appliquées à l’éco-système iOS, qui fonctionne légèrement différemment.

Une autre bibliothèque présentée est la bibliothèque Resources. Celle-ci ne permet ni plus ni moins que d’enfin pouvoir gérer ses images, strings, dimensions, etc, au sein du module partagé, de la même manière que les resources sur android ! Plus besoin de système fait maison ou d’une bibliothèque tierce dont la durée de vie est inconnue. Pas de doute sur le fait que celle-ci sera vite adoptée par les utilisateurs si les premiers retours sont bons.

Toujours du côté du tooling, Márton parle de Fleet, le nouvel IDE de Jetbrains. Celui-ci prétend gérer une multitude de langages de programmation dont Kotlin, Swift et Javascript. Cela en fait donc un candidat idéal pour gérer les projets KM. Marton nous fait alors une rapide démonstration de l’IDE. A noter que celui-ci est gratuit car il est en bêta publique mais redeviendra payant (pour la version complète) à terme, suivant le modèle des autres IDE JetBrains.

Le dernier point abordé est l’outil Amper. Amper est un outil de configuration de projet basé sur du yaml et permet une déclaration simplifiée des caractéristiques de ses modules gradle. Amper intervient en complément de Gradle et vise à terme à remplacer le build.gradle. Sous Fleet, le fichier yaml dispose de l’auto-complétion mais on peut se poser la question de savoir si un fichier yaml est plus facile d’utilisation lorsque le fichier gradle (en kts) permet l’auto-complétion également. On peut voir un exemple d’utilisation sur l’image ci-dessous.

On a là un beau résumé de l’état de l’art de Kotlin Multiplatform. Toutes ces annonces nous donnent l’eau à la bouche. Néanmoins, il faudra attendre de voir comment tous ces framework/outils se comportent dans les conditions du réel. Avec beaucoup d’annotations “experimental” ou “alpha”, beaucoup de ces apis sont peut-être amenées à changer.

Why is adaptive layout a nightmare

David Ta & Gérard Paligot nous ont présenté un talk fascinant lors duquel ils ont abordé les défis liés à la construction d'un écran compatible avec n'importe quel appareil.

Dans la quête perpétuelle de concevoir des écrans compatibles avec n'importe quel appareil, les développeurs Android sont confrontés à un défi de taille : la mise en page adaptative. Mais pourquoi est-ce si difficile ?

  • Quel est le problème ?

Les outils actuellement disponibles et utilisés pour mettre en place des écrans adaptatifs à n’importe quelle taille d’écran ne sont actuellement que très peu conviviaux pour les développeurs et manquent de modularité. On pense notamment aux agencements adaptatifs via les composants et des concepts tels que WindowInset, WindowManager et WindowSizeClasses pour gérer les configurations des appareils. WindowManager, par exemple, est crucial car il gère toutes les données de configuration de l'appareil, tandis que WindowSizeClasses permettent de concevoir, de développer ou de tester les applications en fonction des différentes tailles d'écran.

La complexité est exacerbée par des éléments tels que les mises en page à deux panneaux, qui, bien que conçues pour améliorer l'expérience utilisateur, peuvent rendre la vie difficile aux développeurs et c’est justement l’un des exemples présenté lors de ce talk.

  • Solution proposée : nouveaux composants de structure

Jetpack Compose propose de nouveaux composants de structure visant à gommer ce manque de modularité et heureusement, il existe des solutions en développement. Les composants tels que Listdetails et NavigationSuiteScaffold présentés durant ce talk ont été introduits pour faciliter la tâche des développeurs, bien qu'ils soient encore en phase alpha et nécessitent des ajustements.

ListDetails: Ce composant offre une solution pour afficher des listes de détails de manière adaptative sur différents écrans. Il permet aux développeurs de créer des interfaces utilisateur dynamiques qui s'adaptent automatiquement aux différentes tailles d'écran, offrant ainsi une expérience utilisateur cohérente.

NavigationSuiteScaffold : Ce composant fournit une structure de base pour gérer la navigation et la disposition de l'interface utilisateur dans les applications Android. Il offre des fonctionnalités avancées pour personnaliser la barre de navigation et simplifier la gestion des différentes configurations d'écran, notamment en mode paysage.

  • Implémentation dans une application réelle

Dans la vie réelle, la mise en œuvre de ces concepts nécessite une révision de l'architecture des composants. Bien que les modules principaux restent inchangés, l'ajout de modules centraux dédiés aux styles permet une plus grande cohérence visuelle à travers l'application.

Un autre défi est la gestion du mode paysage, où des variantes de taille doivent être prises en compte. Cela peut impliquer des ajustements dans la disposition de l'interface utilisateur, comme le remplacement d'un bouton de filtre par un écran de filtre complet lorsque le mode paysage est activé.

Les appareils tablettes et pliables prennent dès lors une importance capitale et croissante dans le domaine de la conception adaptative, et leur intégration nécessite une attention toute particulière, tout comme l'utilisation de NavigationSuiteScaffold pour personnaliser les barres de navigation en mode paysage.

  • Points de frictions

Bien que les outils de structure proposés par Google ne soient pas prêts à être utilisés immédiatement selon nos speakers en raison de leur caractère restrictif et de leur instabilité, ils représentent une piste intéressante pour l'avenir du développement d'applications adaptatives.

Cet exposé a mis en lumière les défis et les opportunités dans le domaine de l'agencement adaptatif, offrant aux développeurs une vision précieuse pour la création d'interfaces utilisateur flexibles et optimisées pour une variété d'appareils et nous remercions David Ta & Gérard Paligot de nous avoir partagé leur point de vue sur la question.

Crime Scene InvestiGITor

Benjamin Kadel - Principal Platform Engineer for Android at Babbel

Dans un talk avec très sûrement l’une des meilleures mises en scène d’Android Makers, Benjamin Kadel nous plonge dans les méandres de Git au travers d’un scénario de scène de crime.

Le crime ? Un commit a cassé un test unitaire, ou a inséré un bug dans un projet, et il faut trouver le coupable et surtout, réparer tout ça ! C’est là qu’entre en scène le Detective Kadel.

Dans un premier temps, il nous présente un rapide récapitulatif de Git, notamment comment il fonctionne (le fait que chaque commit a un ID unique qui est en fait une empreinte SHA1 créé à partir du contenu du commit), la notion de “parents” ou encore les différents types d’objets autres que des commits, et comment ils sont stockés. Il repasse aussi sur certaines commandes relativement communes telles que git status, git add, git commit, etc.

Il enchaîne ensuite sur comment “remonter le temps” pour retrouver un commit “fautif”, c’est-à-dire celui qui a causé les problèmes de test unitaire ou de bug par exemple. La première est à l’aide du git checkout qui peut permettre de remonter à un moment précis dans l’historique, git revert qui permet de créer un nouveau commit qui est le total opposé d’un commit en question, ou encore git reset qui permet de faire un reset dans l’historique (à ne faire que sur une branche locale, bien évidemment 😀)

Il nous présente ensuite la façon la plus simple, avec la commande git bisect. Cette commande permet, via un algorithme, de trouver quel commit dans l’historique a pu introduire le bug. On va définir un “bon” commit (git bisect good <ref>), celui qui n’a pas le bug, et un “mauvais” commit (git bisect bad <ref>), celui qui a le bug. L’algorithme va ainsi réduire la plage jusqu’à trouver le commit défaillant. Dans les faits, on va faire jouer les tests à chaque commit pour ainsi définir les bons commits et extraire le mauvais. Une fois ce dernier trouvé, on pourra faire un git bisect reset.

Mais il y a un autre problème : un fichier sensible a été involontairement (ou volontairement ?) ajouté dans l’historique. Il est simple d’ajouter un nouveau commit en ayant supprimé ce fichier, mais comment faire pour qu’il disparaisse complètement de l’historique Git ? Il faut alors réécrire cet historique grâce à la commande git-filter-branch avec notamment le paramètre --index-filter qui va permettre de supprimer le fichier en question au niveau de l’index, et non du disque. Le journal de révision contient donc toujours une référence à ce fichier.
Cependant, il recommande pour ce genre d’opération l’utilisation de git-filter-repo qui est un plugin non-natif de Git et qui est plus récent.

Si vous souhaitez plus d’info, Benjamin Kadel a créé plusieurs vidéos YouTube expliquant les différents mécanismes de Git : https://www.youtube.com/playlist?list=PL3Y9MECuxct0RMwdYcqoIjo-7ncRpTNLs)

Son lien Linktree : https://linktr.ee/bkadel

Un grand bravo à lui pour cette belle mise en scène et ce talk ô combien intéressant !

Kotlin reflection

Danny Preussler - Android Developer at Soundcloud

La présentation, proposée par Danny Preussler, Développeur Android chez SoundCloud, s'intéresse à montrer l'usage de la réflexion dans le langage Kotlin. La présentation s'élabore par une suite d'exemples de code.

On peut définir la réflexion (définition issue de wikibook ou voir documentation officielle) de la façon suivante :

"La réflexion (reflection en anglais) permet l'introspection des classes, c'est-à-dire de charger une classe, d'en créer une instance et d'accéder aux membres statiques ou non (appel de méthodes, lire et écrire les attributs) sans connaître la classe par avance."

Pour commencer avec la réflexion, il faut rappeler l’usage de KClass. Ce type permet de récupérer les informations d’une classe au runtime et est possible de cette manière :

val refMyClass = MyClass::class

A travers la référence refMyClass, nous avons accès à un ensemble d’informations concernant la classe référencée (est-ce une data class, membres internes, classe scellée ou ouverte, visibilité …).

Pour obtenir le type d’une classe ou de déclaration(s) optionnelle(s) à une classe, l’usage KType est approprié. Il est aussi utile pour vérifier si le type est concerné par la nullabilité.

L’introspection des méthodes, propriétés et constructeurs se basent toutes sur le type parent KCallable (appelé callable reference):

  • KFunction est utilisé pour l’introspection de méthode. KFunction permet entre autres de connaître le nom de la méthode, ses paramètres, son accessibilité, type de retour …
  • KProperty concerne la réflection sur les propriétés en lecture (val). Elle se limite donc aux getters (en plus des informations d’accès, si c’est une constante, initialisé tardivement (late init), etc). Pour les propriétés en lecture/écriture (var), il faut utiliser KMutableProperty.
  • Le cas des constructeurs peut être considéré comme un sous cas de méthode via KFunction. Il est à noter que les constructeurs d’une class Kotlin sont disponible dans le champ constructors de KClass (et l’accès au constructeur par défaut primaryConstructor si implémenté).

L’interopérabilité de Java dans Kotlin a été rappelée dans le but que cette intéorpérabilité est aussi présente dans la reflection de Kotlin.

Pour conclure cette présentation, le présentateur a rappelé le coût en performance qu’a l’utilisation de l’introspection de Kotlin. Le non-accès aux entrées déclarées private a été évoquée (chose possible avec Java). Un dernier point qui ne fut pas dit explicitement dans cette présentation est que l’API Kotlin reflection n’est pas encore officiellement disponible (en release candidate durant la rédaction de cet article).

The environmental impact of mobile apps: Truth or Dare?

Fanny Demey, Emmanuel Demey - Développeuse mobile et GDE, expert Frontend - La vidéo

Photo par Soriya Thach - Truth: How did we get there?

La photo ci-dessus illustre une vérité bien dérangeante : c’est au Ghana, dans l’une de ces nombreuses décharges, que finissent tous nos objets électroniques. Le constat est sans appel : c’est un réel danger tant pour l’environnement que pour les populations y travaillant.

Mais comment en sommes-nous arrivés là ?

Déjà, il faut avoir en tête que l’impact dont nous parlons inclut non seulement les émissions de gaz à effet de serre, mais aussi les consommations d’eau, de ressources et d’énergie. Par souci de temps, Fanny et Emmanuel Demey ne se sont concentrés que sur le premier point durant ce talk.

L’univers du numérique de 2010 à 2025 - Issu du rapport d’étude sur l’empreinte environnementale du numérique mondial


Si l’on regarde les chiffres sur l’empreinte du numérique à l’échelle mondiale, on observe que de 2015 à 2025, le nombre d’utilisateurs, d’équipements classiques et de taux d’équipement évolue peu. En revanche, en incluant les objets connectés (IoT) on en vient à presque tripler le nombre d’équipements !

Pour rappel, les utilisateurs finaux représentent 66% des émissions de gaz à effet de serre dont une grande partie est liée à la production. Ajoutons à cela l’obsolescence programmée, les modes de consommation, la facilité d’accès à tous ces équipements… il est aisé d’en oublier les conséquences :

  • La raréfaction des métaux nécessaires à la construction de nos téléphones et ordinateurs. Par exemple, pour obtenir une tonne de Gallium, il faut déplacer environ 50 tonnes de roche !
  • Le travail des enfants dans les mines, notamment en République Démocratique du Congo.
  • Le déplacement de tout un village en Allemagne pour exploiter et excaver les sols.
  • L’entassement des déchets électroniques au Ghana.

Tout cela nous amène à questionner nos usages et notre consommation d'objets électroniques.

Photo par Soriya Thach - Dare: What can we do?


Maintenant que nous savons pourquoi la situation est telle aujourd’hui, que pouvons-nous faire pour agir ?

Bien que le talk s’adresse en premier lieu aux développeurs.ses, il est bon de rappeler quelques actions applicables en tant qu’utilisateur : réduire sa consommation de gadgets en tout genre, se tourner vers le reconditionnement, prendre soin de ce que nous possédons déjà… mais pas que ! Il y a également toute une dimension autour de l’éducation et de la reconsidération de nos usages.

Et en tant que développeur.se ?

Déjà, suivre les bonnes pratiques établies par des entités telles que greenit.fr ou encore le référentiel général d’écoconception de services numériques. Mais le vrai message derrière, c’est que nous sommes responsables !

“Don’t be the app that makes your user renew their phones.”

Nous sommes les premiers acteurs et notre impact est considérable ! Avec le collectif IT’s on us, Fanny et Emmanuel Demey donnent 5 zones sur lesquelles nous pouvons agir pour le mobile.

1. Spécification :

  • Dimensionner les fonctionnalités à développer pour mieux anticiper les besoins réels.
  • Optimiser les parcours utilisateur.
  • Adopter un design simple et épuré.
  • Retirer toutes les fonctionnalités inutilisées car la plupart ne sont pas voire peu utilisées !

2. Réseau :

  • Éviter de récupérer toutes les données de l’app à l’état `Resumed` afin de ne pas surcharger les appels côté serveur.
  • Utiliser la stratégie de `lazy loading`.
  • Mettre en place du cache pour les images fournies côté serveur.
  • Penser son app en priorité en mode hors connexion.
  • Limiter le nombre d’outils de tracking qui peuvent être gourmands en requêtes et augmenter la taille de l’app.
  • Optimiser les requêtes HTTP (nombre de requêtes, la résolution du contenu, les formats de contenu, etc.).

3. Mémoire :

  • Limiter les opérations complexes sur les données fournies par le serveur.
  • Éviter de faire des requêtes SQL dans des boucles.
  • Mettre en cache les objets qui sont coûteux à instancier.
  • Libérer les ressources inutilisées.
  • Améliorer nos Composables.

4. Stockage :

  • Retirer les dépendances et ressources inutilisées.
  • Minifier le code afin de réduire la taille de l’application.
  • Stocker uniquement les données nécessaires.
  • Réduire le nombre de ressources utilisées et leur taille.

Pour mieux comprendre la gestion du stockage, on peut mesurer la taille de notre application avec ces quatre métriques : les tailles de téléchargement et de mise à jour (côté réseau), les tailles d’installation et de stockage (installation + cache + base de données…).

5. Compatibilité :

  • Faire attention au choix de la cible du SDK minimal.
  • Tester son application dans des conditions minimales, qui sont souvent bien plus proches de la réalité que nos environnements optimaux !

Forts de ces conseils, nous pouvons dès à présent faire la démarche de mieux penser nos applications pour limiter notre impact environnemental !

Un grand merci à Fanny et Emmanuel pour cette prise de conscience collective !

Composables dans les Vues: L'interopérabilité et la Confrontation des Cycles de Vie?

par Pierre-Emmanuel Altieri et Mohammed Boukadir - tous les deux Senior Android engineer chez Backmarket - La vidéo

Pierre-Emmanuel et Mohammed sont ingénieurs chez Backmarket, le leader du reconditionné sur le numérique. Pierre-Emmanuel est membre de l'équipe core. C'est à dire qu'il crée des outils qui permettent aux développeurs.euses de mieux travailler. Mohammed est dans l'équipe care. Son but : apporter des fonctionnalités qui prennent "soin" de l'utilisateur. Par exemple : suivre sa commande, consulter son compte, etc.

L'application backmarket c'est plus de 200 modules et plus de 5 ans d'existence. L'essentiel des vues étaient donc en XML. Les équipes ont ensuite voulu migrer sur Jetpack Compose. Mais comment faire? Ils ont imaginé deux stratégies :
1. Toutes les équipes sont à 100% sur la refonte pendant 6 mois. La méthode "Aragorn", ou "Yolo".
2. Changer progressivement l'application en compose, en faisant une abstraction. La méthode "Scooby-Doo". En l'occurence, c'était 3 membres de l'équipe core qui faisaient ce travail. Les équipes utilisent l'abstraction, et l'équipe core change l'implémentation petit à petit de View à Compose. Avantage de la démarche: les équipes ont le temps d'apprendre à leur rythme, et les roadmaps ne sont pas bloquées par la refonte.

Ils ont choisi la méthode 2. Dans le détail, l'abstraction consiste à encapsuler les composants dans une AbstractComposeView. Cette classe est un bridge entre Compose et Android View. C'est via la méthode Content(), qui est composable, qu'on décrit le contenu du composant.

class MyComposeView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
) : AbstractComposeView(context, attrs, defStyleAttr) {


    @Composable
    override fun Content() {
        Text(text = "Bonjour")
    }
}

Ensuite, on intègre le composant classiquement s'il n'existait pas, ou on ne change rien s'il était déjà en place : l'avantage de l'abstraction!

La migration s'est déroulée sans encompre jusqu'à ce que des soucis de performance (fuite mémoire) et de scroll (flickering) apparaissent. Après investigation, Pierre-Emmanuel et Mohammed ont découvert qu'il y avait beaucoup trop de recompositions. L'écran étudié contenait une recyclerview. Ce composant limite normalement la création de vues. En effet, comme son nom l'indique, un système de cache permet de recycler des vues déjà créées. À vrai dire, les soucis venaient de l'utilisation de RecyclerViews imbriquées. Les composants n'étaient pas correctement mis en cache et donc se recréaient systématiquement. Un changement du mécanisme d'encapsulation a permis de résoudre la problématique.

Pour rentrer dans plus de détails, je vous invite à regarder leur talk. Un super retour d'expérience d'une migration Android View vers Compose, dans une app non triviale :-) Merci!

Le mot de la fin

Et voilà, deux jours plus tard, c’est déjà fini ! Tristes de rentrer, mais déjà prêts à repartir pour l’édition 2025 ! S’il y a bien une chose qui ne change pas c’est l’ambiance formidable de cet événement, l’organisation au pixel près et surtout un beau moment d’échange entre passionnés.

Vous avez pu lire cet article jusqu'au bout ? Allez, en cadeau, les talks de nos collègues Ailton LOPES MENDES et Justine PATACO qui nous ont régalé avec un talk sur Gemini AI, ainsi que Willy ROUVRE avec l’animation d’une table ronde sur le MobileOps !

On peut sereinement se dire : “À l’année prochaine !”.