Cet article est une traduction de la publication en anglais sur Medium.

Pas plus tard qu'hier, j'ai voulu tester la dernière version bêta de Flutter. Alors que je n'avais jamais rencontré de problème majeur avec ce framework, je me suis confronté à mon premier bug qui m'a occupé pendant quelques heures...

Ma réaction hier...

Tout bon développeur vous le dira, une bonne pratique est de toujours utiliser des versions stables, afin d'éviter d'inutiles complications.

Mais comme vous le savez peut-être, la semaine prochaine, Google organisera un événement - le Flutter Interact - où une nouvelle version de Flutter devrait être rendue disponible.

Comment tester une version bêta de Flutter ?

Flutter est découpé en plusieurs branches (ou versions) : stable, beta, dev et master (par ordre de stabilité).

Vous pouvez facilement visualiser sur quelle branche vous vous trouvez actuellement avec la commande flutter channel :

~|⇒ flutter channel

Flutter channels:
* stable
  dev
  master
  beta

Basculer d'une branche à l'autre se fait aussi simplement qu'avec cette commande :

~|⇒ flutter channel nouveauchannel

Note : n'oubliez pas d'exécuter la commande flutter upgrade juste après, afin de resynchroniser votre ordinateur avec le dépôt central.

Mais quel est le problème sur cette bêta ?

Comme vous le savez peut-être, Flutter a plusieurs modes de fonctionnement, dont :

  • Release : génère une application pour le Google Play ou l'AppStore
  • Debug : utilisé lors de vos développements

En ce qui concerne le mode release, tout fonctionne parfaitement avec la bêta. Que vous souhaitiez générer une IPA (iOS), un App Bundle ou un APK (Android) à partir de votre projet Flutter, il n'y a aucun changement majeur à noter entre versions stable et bêta.

Mais lorsque j'ai voulu exécuter mon application pour commencer à faire des modifications dessus, j'ai rencontré cette erreur étrange :

Launching lib/main.dart on AOSP on IA Emulator in debug mode...
Running Gradle task 'assembleDebug'...

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':app:compileInternalDebugKotlin'.
> Could not resolve all files for configuration ':app:internalReleaseRuntimeClasspath'.
   > Could not find io.flutter:x86_release:1.0.0-af04338413c3ed73316350f64248a152433073b6.
     Searched in the following locations:
       - https://dl.google.com/dl/android/maven2/io/flutter/x86_release/1.0.0-af04338413c3ed73316350f64248a152433073b6/x86_release-1.0.0-af04338413c3ed73316350f64248a152433073b6.pom
       - https://dl.google.com/dl/android/maven2/io/flutter/x86_release/1.0.0-af04338413c3ed73316350f64248a152433073b6/x86_release-1.0.0-af04338413c3ed73316350f64248a152433073b6.jar
       - https://jcenter.bintray.com/io/flutter/x86_release/1.0.0-af04338413c3ed73316350f64248a152433073b6/x86_release-1.0.0-af04338413c3ed73316350f64248a152433073b6.pom
       - https://jcenter.bintray.com/io/flutter/x86_release/1.0.0-af04338413c3ed73316350f64248a152433073b6/x86_release-1.0.0-af04338413c3ed73316350f64248a152433073b6.jar
       - http://download.flutter.io/io/flutter/x86_release/1.0.0-af04338413c3ed73316350f64248a152433073b6/x86_release-1.0.0-af04338413c3ed73316350f64248a152433073b6.pom
       - http://download.flutter.io/io/flutter/x86_release/1.0.0-af04338413c3ed73316350f64248a152433073b6/x86_release-1.0.0-af04338413c3ed73316350f64248a152433073b6.jar
     Required by:
         project :app

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 31s
Finished with error: Gradle task assembleDebug failed with exit code 1

En lisant rapidement, on comprend qu'il s'agit d'une dépendance manquante. Mais comment se fait-il que tout fonctionnait en mode release ?

En y regardant d'un peu plus près, on se rend alors compte qu'une dépendance x86 est manquante. Ni une, ni deux, j'ai donc testé sur mon smartphone qui a un processeur ARM… et cette fois-ci plus aucune erreur 🤨.

Le problème vient de l'émulateur

Je ne l'avais jamais remarqué jusqu'alors, mais l'ensemble de mes AVDs (Android Virtual Devices = émulateurs Android) utilisaient une image x86. Et en passant vers une image de type x86_64 bits, mon problème s'est résolu par lui-même.

La liste de vos AVDs

Qu'ai-je appris ici ? Avant de procéder à la migration vers la prochaine version de Flutter, assurez-vous de basculer l'ensemble de vos émulateurs Android vers des images x86_64... sinon vous vous trouverez bloqués comme moi !

Mais pourquoi Google a-t-il fait ce changement ?

Jusqu'à présent, vous pouvez débogguer vos applications Flutter sur un émulateur Android (x86 ou x86_64), mais il est impossible de générer (mode release) une application pour les boutiques d'applications.

Si je cite la FAQ de Flutter :

Actuellement Flutter ne support pas le build vers Android x86 (bug #9253).

Toutefois les applications conçues pour ARMv7 ou ARM64 fonctionnent (via l'émulation ARM) sur de nombreux terminaux Android x86.

L'équipe Flutter semble donc avoir changé d'avis sur le sujet (= part de marché trop faible du X86 pour y consacrer du temps), puisqu'une Pull Request a récemment été validé et permet non seulement de débogguer en x86_64 bits, mais aussi d'utiliser le mode release avec cette architecture. C'est donc pour cette raison que l'image x86 ne fonctionne plus, car seul le x86_64 bits est supporté.

Après avoir perdu du temps dans les issues et le code sur GitHub, il aurait vraiement été bienvenue d'avoir un message plus explicite que celui-ci. Espérons qu'ils aient le temps de faire cette petite modification d'ici à l'événement du 11 décembre.

N'oubliez pas de mettre à jour votre code

La prochaine version de Flutter ne va pas uniquement casser vos émulateurs Android, elle va également générer un certains nombres de warnings.

Le plus important est celui relatif à la méthode inheritFromWidgetOfExactType de la classe State qui est désormais dépréciée. Pour les plus curieux, les explications sont dans la PR sur GitHub.

La commande flutter analyze va désormais vous afficher ce type d'erreur :

info • 'inheritFromWidgetOfExactType' is deprecated and shouldn't be used. Use dependOnInheritedWidgetOfExactType instead.

Il ne reste donc qu'à appliquer ce qui est indiqué en transformant votre code. Il faut pour cela passer de :

InheritedWidget inheritFromWidgetOfExactType(Type targetType, { Object aspect });
Ex : context.inheritFromWidgetOfExactType(YourInheritedWidget)

A :

T dependOnInheritedWidgetOfExactType({ Object aspect });
Ex : context.dependOnInheritedWidgetOfExactType()

Vous êtes maintenant prêts pour la prochaine version de Flutter ! 🥳