Récemment, nous avons complètement repensé l'application Pyrus pour Android. La première version de l'application fonctionnait déjà sous Android 2.2. Refusant de prendre en charge Android en dessous de 4.1, nous avons pu rembourser la dette technique accumulée et simplifier considérablement le code source. Oui, nous avons perdu une partie des utilisateurs (moins de 1%), mais d'un autre côté, nous avons économisé du temps aux développeurs pour corriger des bugs rares. Nous pourrons l'investir dans le développement de fonctionnalités pour tous les utilisateurs actuels et nouveaux. À long terme, cela est beaucoup plus important.
Nous partageons ici des expériences qui peuvent être utiles à ceux qui envisagent de commencer le développement de la plate-forme Android.
Android attire de bons outils de développement, un langage éprouvé (Java) avec la syntaxe habituelle, un large public d'utilisateurs. Cependant, créer des applications pratiques sur Android est difficile: malgré l'API développée, il arrive souvent qu'il n'y ait pas de composant prêt à l'emploi avec un comportement approprié. Vous devez soit abandonner les idées du concepteur UX, soit accepter de dépendre de bibliothèques tierces, soit vous écrire. Toutes les solutions architecturales d'Android ne se sont pas avérées efficaces, ce qui augmente également la quantité de code sans bénéfice évident.
Mourir et renaître de ses cendres
L'interface dans Android est basée sur Activity. Il s'agit d'un conteneur qui occupe généralement la totalité de l'écran de l'appareil, d'autres widgets y vivent et il reçoit des événements sur l'interaction de l'utilisateur.
Lorsque l'utilisateur active l'application, un événement onResume est lancé dans l'activité. Appuyez sur le bouton Accueil - L'activité a disparu, mais avant cela, il a reçu l'événement onPause. Jusqu'à présent, tout est logique. Que se passe-t-il lorsqu'un utilisateur fait pivoter l'écran de l'appareil de 90 degrés? Vous ne devinerez jamais: le système d'exploitation tue l'activité et recrée! Lorsque vous désinstallez une activité, tous les composants qu'elle contient sont supprimés. Cela signifie que vous devez écrire du code spécial qui enregistre l'état des widgets à l'intérieur de l'activité (position de défilement, texte sélectionné, état des cases à cocher) et les restaure après la recréation du parent. Android fait une partie de ce travail pour vous, mais pas tout.
Il est difficile de comprendre ce qui a poussé les architectes à prendre une telle décision. Plus tard, quelqu'un a décidé que cela avait l'air laid et a ajouté le même paramètre, qui supprime le comportement par défaut du système. Désormais, au lieu de recréer Activity, le système d'exploitation peut appeler la méthode spéciale onConfigurationChanged. Cette «solution» ressemble à un hack sale et n'a fait qu'exacerber le problème, car la documentation Android
indique que «cette technique doit être considérée comme une mesure extrême et n'est pas recommandée pour la plupart des applications».
Fragments fragmentés
Initialement, le système d'exploitation Android a été créé pour les téléphones. Avec l'avènement des tablettes, l'équipe Android a décidé à juste titre que les éléments d'interface qui étaient auparavant espacés par différentes activités en raison de la petite taille de l'écran du téléphone peuvent désormais coexister sur le grand écran de la tablette. (Exemple: la liste des lettres et l'e-mail sur le téléphone étaient dans deux activités différentes, et sur la tablette, ils partageaient un écran ensemble.) Oui, le problème est: plusieurs activités ne peuvent pas simultanément interagir avec l'utilisateur par conception. Par conséquent, un autre mécanisme de réutilisation des composants est nécessaire, et une solution a été trouvée: des fragments sont apparus (Fragment).
Par
définition , un fragment représente un comportement ou une partie d'une interface utilisateur dans une activité. Tout est clair. Cependant, dans les instructions d'utilisation des fragments, nous trouvons la section «Ajouter un fragment qui n'a pas d'interface utilisateur». QUOI? Il s'avère qu'un fragment peut ne pas avoir sa propre fenêtre de rendu!
Mais qu'arrive-t-il aux fragments lorsque l'on tourne l'écran? Les développeurs Android y ont pensé - lorsque vous recréez une activité, tous ses fragments sont également recréés automatiquement. Cependant, après un examen attentif, le fragment a la méthode "setRetainInstance", si vous l'appelez, ce fragment ne sera pas supprimé et restauré pendant les tours.
Élancé et cohérent, ce concept ne peut pas être appelé.
Fonctionnement asynchrone
Le thread de traitement des événements ne peut pas être bloqué par de longues opérations, l'échange de données avec le disque et le réseau doit donc être effectué de manière asynchrone dans les autres threads. Android propose jusqu'à quatre mécanismes de fonctionnement asynchrone: AsyncTask, Service, IntentService, Thread. Les développeurs sont encouragés à déterminer celui qui leur convient le mieux. Le choix n'est pas anodin: par exemple, si l'application a démarré AsyncTask et que l'utilisateur a tourné l'écran pendant son exécution, à la fin du travail, AsyncTask n'est pas en mesure de trouver une nouvelle activité (créée après le tour). Et aucun des quatre mécanismes n'implémente une logique simple: si l'utilisateur a démarré le deuxième processus asynchrone sans attendre les résultats du premier, puis le premier s'est terminé plus tôt, il convient alors d'ignorer et de ne pas refléter ses résultats dans l'interface utilisateur.
Il devient clair l'apparition de nombreuses bibliothèques - des bus de données pour organiser le travail asynchrone dans une application Android.
Redémarrage de l'application après OOM
Si Android manque de RAM libre, le système d'exploitation peut terminer n'importe quel processus. Lorsque l'utilisateur activera ultérieurement l'application, le système tentera de restaurer son état. En théorie, cela devrait être invisible pour le développeur (s'il a implémenté la méthode onSaveInstanceState dans tous les composants): le système lui-même recrée la pile d'activité telle qu'elle était lors de l'arrêt forcé. Cependant, si l'initialisation prend du temps (par exemple, le chargement de caches à partir du disque ou du réseau), il sera correct d'afficher à l'utilisateur un indicateur d'attente. Il s'avère que lors de la création d'une activité, vous devez toujours surveiller le «démarrage à froid» et effectuer l'initialisation manuellement. Sans oublier qu'au redémarrage, aucun Thread et AsyncTask ne sont restaurés.
Quelle est la probabilité de manquer de mémoire dans la pratique? En règle générale, cette situation se produit lors du traitement d'images haute résolution. Par exemple, une image 2048x1536 occupe 12 Mo dans la mémoire d'un objet Bitmap. La quantité de mémoire disponible pour l'application dépend du modèle de périphérique spécifique et est parfois très petite (64 Mo ou 128 Mo). Étant donné que le garbage collector dans toutes les versions d'Android antérieures à 8.0 n'était pas compact, même si vous avez 100 Mo de mémoire libre, mais qu'il est divisé en blocs de 10 Mo, une tentative d'allocation de mémoire pour une telle image a entraîné un blocage de l'application.
Collecte des ordures éternelle
Une fois que notre utilisateur a remarqué que lors du défilement de longues listes, l'application était «en retard» - toutes les 2-3 secondes, l'animation s'arrêtait pendant de courtes pauses (200-300 ms), puis continuait. L'analyse a montré que la collecte des ordures commence souvent de manière suspecte dans l'application. Il s'est avéré que la classe HashMap standard (que nous utilisons pour obtenir un objet Java par son ID) est inefficace dans notre cas: nous devons créer un objet wrapper pour chaque clé, qui est un entier (int). Par conséquent, le nombre d'allocations de mémoire augmente sans aucun avantage. La solution a été de passer à un conteneur SparseArray spécial (disponible uniquement dans Android, pas dans la plate-forme Java standard), ce qui a immédiatement réduit la pression sur le garbage collector.
Quel est le retard dans l'animation, demandez-vous? Le fait est que le garbage collector dans Android a arrêté tous les threads pendant son fonctionnement, y compris le thread principal impliqué dans le rendu. Dans les versions d'Android à partir de 5.0, une autre machine virtuelle est utilisée (ART au lieu de Dalvik) et un algorithme de collecte des ordures différent, qui interrompt de moins en moins l'animation. (Vous pouvez en savoir plus sur la comparaison du temps de collecte des ordures
ici .)
Afficher les documents
Si vous souhaitez insérer des aperçus de documents dans votre application, vous êtes obligé de décevoir: dans Android, il n'y a pas de composant intégré qui peut afficher les fichiers Word, Excel, Powerpoint. Sans parler des archives ZIP ou des documents PDF. Sortir? Forcer l'utilisateur à installer des applications tierces pour afficher chaque type de fichier ou utiliser le composant WebView (en fait un navigateur). Dans les deux cas, lorsque l'utilisateur enregistre le fichier, une application externe est lancée et certains scénarios ne peuvent tout simplement pas être mis en œuvre, par exemple un flux d'images: il n'y a pas de moyen facile d'intégrer WebView dans un ViewPager standard.
Et ensuite
Certaines études affirment que la
complexité du développement Android est relativement élevée . Notre expérience montre qu'il est facile pour un développeur compétent de s'habituer aux fonctionnalités de cette plateforme. Et bien qu'Android soit aujourd'hui le
système d'exploitation mobile le
plus populaire au monde , dans 5 à 10 ans, la situation pourrait radicalement changer.
Ces dernières années, Google a secrètement développé le
nouveau Fuchsia OC avec un modèle de sécurité fondamentalement différent (par rapport au système d'exploitation moderne). Il utilisera probablement
Dart comme langage de programmation principal et le framework
Flutter comme moyen principal de créer des applications. La rumeur veut que
Fuchsia puisse remplacer Android et ChromeOS sur tous les appareils. Si Google le fait, la société est susceptible de fournir un support natif pour les applications écrites pour Android (comme Microsoft l'a fait lors du passage de DOS à Windows). Par conséquent, jusqu'à présent, vous ne pouvez pas vous inquiéter et continuer à accumuler une expertise dans Android. Et pour ceux qui veulent regarder vers l'avenir, vous pouvez télécharger Flutter et jouer avec
ici .