MFormations
Modern Mobile Engineering

Chapitre 1

01 - Fondamentaux Mobile

01 - Fondamentaux Mobile

01 - Fondamentaux Mobile : Cours complet

Table des matières

  1. App lifecycle
  2. Concurrence mobile
  3. Gestion mémoire
  4. UI & design systems (Material 3, HIG)
  5. Accessibilité mobile
  6. Background execution
  7. Batterie
  8. Offline
  9. Stores (Play Store, App Store)
  10. Résumé et checklist

1. App lifecycle

Le lifecycle décrit les états par lesquels passe une application mobile. Le comprendre est essentiel : c'est là que se règlent la persistance d'état, les abonnements réseau et la libération des ressources.

1.1 Android : Activity

États d'une Activity :

ÉtatMéthodeRôle
CrééeonCreate()Initialisation unique, inflate du layout
DémarreonStart()L'app devient visible
RepriseonResume()Prête à interagir, focus
PauseonPause()Plus de focus (dialog, multi-tâche), court
ArrêtéeonStop()Plus visible du tout
DétruiteonDestroy()Libération des ressources
RecrééeonRestart()Retour depuis l'état stoppé
Diagramme en cours de génération...

Règles d'or Android :

  • Ne jamais bloquer le thread principal (main/UI thread).
  • onPause/onStop : stopper les animations et tâches lourdes.
  • Sauvegarder l'état UI dans onSaveInstanceState et via ViewModel.
  • En cas de kill par l'OS (manque de mémoire), le process peut mourir sans onDestroy : utiliser ViewModel + SavedStateHandle pour la persistance.

1.2 Android : Fragment

Un Fragment a sa propre vie au sein d'une Activity :

onAttach → onCreate → onCreateView → onViewCreated → onStart → onResume → onPause → onStop → onDestroyView → onDestroy → onDetach

Les Fragments existent pour la modularité et l'adaptation tablette (deux panneaux). Depuis 2024, Google recommande de limiter les Fragments et de privilégier des API plus simples, mais ils restent très répandus dans la maintenance.

1.3 iOS : UIApplicationDelegate + Scene

Depuis iOS 13, l'application est gérée par la Scene (une fenêtre d'app). Le UIApplicationDelegate gère le lancement, les scènes sont gérées par le UISceneDelegate (ex. UIWindowSceneDelegate).

États de l'app (iOS) :

ÉtatDescription
Not runningProcess arrêté
InactiveVisible mais pas de recevabilité (transition, écran de verrouillage)
ActiveRéception des événements
BackgroundEn arrière-plan, temps limité (~30 s, ou tâche étendue)
SuspendedGelé en mémoire, pas de code exécuté
Diagramme en cours de génération...

sceneDidEnterBackground, sceneWillEnterForeground sont les hooks SwiftUI/UIKit modernes.

Règles d'or iOS :

  • Pas de travail long dans applicationDidEnterBackground.
  • Utiliser beginBackgroundTask(expirationHandler:) pour les tâches courtes (≤ 30 s).
  • Sauvegarder l'état dans les SceneStorage/AppStorage et via le modèle de données.

1.4 React Native : lifecycle

RN repose sur React : le composant a un cycle componentDidMount → componentDidUpdate → componentWillUnmount, exprimé avec useEffect dans les hooks. L'application elle-même réagit aux événements natifs : AppState.

import { AppState } from "react-native";

const subscription = AppState.addEventListener("change", (state) => {
  // 'active' | 'background' | 'inactive'
  if (state === "background") {
    saveState(); // persister
  }
});

Pièges RN :

  • Le JS s'arrête en arrière-plan : pas de minuterie fiable hors active.
  • Les timers JS dérivent : utiliser Date.now() pour les chronos.

1.5 Flutter : WidgetsBinding

Flutter expose le lifecycle de l'app via WidgetsBindingObserver :

class AppLifecycleObserver with WidgetsBindingObserver {
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.resumed:
      case AppLifecycleState.inactive:
      case AppLifecycleState.paused:
      case AppLifecycleState.detached:
    }
  }
}

Pièges Flutter :

  • En arrière-plan, les timers Dart continuent tant que l'isolate tourne : les stopper en paused.
  • detached : l'engine est encore en vie mais aucun view.

1.6 Synthèse comparée

ÉvénementAndroidiOSRNFlutter
App visibleonStartsceneWillEnterForegroundactiveresumed
App cachéeonStopsceneDidEnterBackgroundbackgroundpaused
Mort du processkill possibleSuspendedJS stoppédetached

2. Concurrence mobile

2.1 Le thread principal (UI thread)

  • Android et iOS : un seul thread UI. Tout travail long le bloque (jank, ANR, « beach ball »).
  • RN : thread JS + thread UI natifs.
  • Flutter : isolate UI + isolate de rendu (raster).

2.2 Modèles de concurrence par plateforme

PlateformeOutils
AndroidKotlin Coroutines, Flow, Dispatchers
iOSGCD (DispatchQueue), OperationQueue, Task (async/await), actor
RNPromises, async/await, Web Workers (partiel), InteractionManager
FlutterIsolates, compute(), Future, Stream

2.3 Bonnes pratiques communes

  1. Ne jamais bloquer l'UI thread : seuil ≈ 16 ms par frame (60 fps), 8 ms pour 120 Hz.
  2. Toujours exécuter le réseau et le calcul lourd hors du thread principal.
  3. Annuler proprement les tâches quand le composant/écran disparaît.
  4. Utiliser des primitives sûres : coroutines structurées, actors, isolates.

2.4 Pièges fréquents

  • Course aux données sur le main thread (UI mise à jour depuis un thread worker sans dispatch).
  • Fuite de tâches : callback qui survit à la destruction du composant → crash ou état fantôme.
  • Deadlock : deux files qui s'attendent mutuellement.
Diagramme en cours de génération...

3. Gestion mémoire

3.1 Les limites du mobile

  • RAM des devices Android : 4–16 Go typiques (grosses variantes 24 Go en 2025–2026).
  • iOS : 4–8 Go selon modèle (iPhone 16 : 8 Go).
  • Pas de swap systématique : le process est tué si trop de mémoire.

3.2 GC (Garbage Collector)

  • Java/Kotlin (ART), Dart : ramasse-miettes par traçage.
  • Avantage : pas de gestion manuelle.
  • Pieds nus : pauses (STW), allocations excessives, références vers des Activity détruites (fuites).
  • Outils : Android Profiler (Memory), LeakCanary.

3.3 ARC (Automatic Reference Counting) — iOS

  • Swift/Objective-C comptent les références.
  • Fuite classique : cycle de références fortes → weak/unowned pour les casser.
  • Outils : Instruments (Leaks), Xcode Memory Graph Debugger.

3.4 Modèle de la mémoire native

  • RN : le JS est géré par Hermes (GC) ; les modules natifs vivent dans leurs runtimes.
  • Flutter : Dart GC ; les ressources natives (images, textures) doivent être libérées.

3.5 Bonnes pratiques

PlateformePratique
AndroidÉviter les Activity leaks (références statiques), utiliser ViewModel
iOS[weak self] dans les closures, valeurs struct plutôt que class
RNLimiter les listeners d'AppState, unmount proprement
Flutterdispose() des controllers, images à taille raisonnable

4. UI & design systems

4.1 Material 3 (Android / multiplateforme)

  • Développé par Google, version 3 (2021) : Material You.
  • Principes : couleur dynamique (palette issue du fond d'écran), formes arrondies, typographie variable, motion expressive.
  • Composants : AppBar, FAB, Cards, NavigationBar, BottomSheet, Snackbar…
  • États : enabled, hovered, focused, pressed, disabled.
  • Implémentation : Jetpack Compose Material 3, Flutter Material 3.

4.2 Human Interface Guidelines (Apple)

  • Principes : clarté, deference (le contenu prime), depth (hiérarchie par la profondeur).
  • Vraies différences : navigation à onglets en bas sur iOS, bouton retour au sommet, « back » par glissement depuis la gauche.
  • Typographie : San Francisco (SF Pro), tailles dynamiques.
  • Composants : NavigationStack, TabView, Sheet, Alert, Context Menu.

4.3 Différences clés à respecter

ConceptAndroid (Material)iOS (HIG)
NavigationBack system + hamburgerBack gesture + back button
Floating actionFAB répanduPeu usité (primary action dans la barre)
SnackbarBas d'écranBas d'écran (rare)
DialogAlertDialogAlert, action sheets
Menu contextuelLong pressLong press + context menu

4.4 Conception responsive

  • Breakpoints : compact (<600 dp), medium (600–840 dp), expanded (>840 dp).
  • Safe areas : encoches (notch), Dynamic Island, barre de navigation gestuelle.
  • Test de grandeurs de police (Dynamic Type iOS, fontScale Android).

5. Accessibilité mobile

5.1 Pourquoi ?

  • 15 % de la population mondiale vit avec un handicap (OMS).
  • Obligation légale dans beaucoup de pays (RGAA en France, ADA, WCAG, EU Accessibility Act).
  • Bonne accessibilité = meilleure UX pour tous.

5.2 Les fondamentaux

  1. TalkBack (Android) / VoiceOver (iOS) : lecteur d'écran.
  2. Cibles tactiles ≥ 48×48 dp (44 pt iOS).
  3. Contraste : ≥ 4.5:1 pour le texte normal.
  4. Ordre de lecture logique (z-order, sémantique).
  5. Alternatives textuelles pour les images ; libellés pour les boutons icon-only.
  6. Respect des réductions de mouvement (Reduce Motion).

5.3 API par plateforme

PlateformeAPI
Composesemantics { contentDescription }, TestTag, clearAndSetSemantics
SwiftUI.accessibilityLabel, .accessibilityIdentifier, .accessibilityElement
RNaccessibilityLabel, accessible, accessibilityRole
FlutterSemantics, label, tooltip, excludeSemantics

5.4 Vérification

  • Parcourir l'app en TalkBack/VoiceOver sur un vrai device.
  • Tester avec les polices ×1.5–2 et le contraste inversé.
  • Lancer les audits : Android Accessibility Scanner, Xcode Accessibility Inspector.

6. Background execution

6.1 Pourquoi c'est contraint ?

La batterie et la bande passante sont des ressources rares. L'OS limite donc l'exécution en arrière-plan pour protéger l'utilisateur.

6.2 Android

  • WorkManager (recommandé) : tâches déléguées garanties (API 23+). Retry, contraintes (réseau, batterie, inactivité), persistance.
  • Foreground service : service visible avec notification persistante (permission FOREGROUND_SERVICE).
  • Les tâches arbitraires en background sont tuées rapidement depuis Android 8+ (limites).
  • Push : FCM (Firebase Cloud Messaging).

6.3 iOS

  • beginBackgroundTask : ~30 s, doit être appelé tôt.
  • BGTaskScheduler : BGAppRefreshTask, BGProcessingTask planifiées par l'OS (pas de garantie d'heure).
  • Push silencieux : autorisé si l'utilisateur garde l'app récente, sinon non.
  • Limitation forte : iOS peut refuser d'exécuter du background pendant des jours.

6.4 RN et Flutter

  • RN : modules natifs (Headless JS, WorkManager via libs).
  • Flutter : plugins (workmanager, background_fetch).
  • Dans les deux cas : le background reste orchestré par le code natif de la plateforme.
Diagramme en cours de génération...

6.5 Règles

  • Toujours annoncer l'usage dans la documentation du store et les permissions.
  • Ne jamais se reposer sur des timers de background.
  • Tester sur un device réel en mode économie d'énergie.

7. Batterie

7.1 Consommation typique

ÉlémentImpact
Écran (luminosité)Le plus gros poste
Radio cellulaire/Wi-FiÉlevé (upload/download)
GPSTrès élevé
CPU/GPUVariable (jeux > app simple)
Écrans OLEDNoir ≈ économe

7.2 Bonnes pratiques

  1. Regrouper les requêtes réseau (paging, batching).
  2. Adapter la fréquence de mise à jour à la visibilité de l'écran.
  3. Éviter le wake lock inutile ; utiliser un seul long-running là où c'est possible.
  4. Images : décoder à la taille d'affichage, utiliser les formats adaptés (WebP/AVIF/HEIC).
  5. Location : startLocationUpdates seulement quand nécessaire, priorité faible par défaut.
  6. Notifications : préférer les push serveur aux pollings.
  7. Suivre les mesures : Battery Historian (Android), Energy Log/Xcode Instruments (iOS).

7.3 Suivi énergétique

  • Android : dumpsys battery , Battery Historian.
  • iOS : Xcode → Energy Log / Instruments → Energy.
  • Utiliser les APIs « Low Power Mode » (Android: PowerManager, iOS: ProcessInfo.processInfo.isLowPowerModeEnabled) pour réduire le travail.

8. Offline

8.1 Stratégies

Diagramme en cours de génération...
StratégieUsage
Cache-firstContenus peu volatils (articles, catalogue)
Network-firstDonnées fraîches prioritaires (messages)
Offline-first + syncSaisie terrain, inventaire, formulaires

8.2 Stack par plateforme

PlateformeBase localeSync
AndroidRoom, DataStoreWorkManager + Réseau
iOSCore Data, SwiftDataCloudKit, BGTask
RNSQLite (react-native-sqlite-storage), MMKV, WatermelonDBreact-native-quick-sqlite + sync custom
Fluttersqflite, drift, Isarplugins + backend
PWAIndexedDBService Worker + Background Sync

8.3 Pièges

  • Gestion des conflits (dernier-écrit gagne est rarement suffisant).
  • Quotas de stockage : l'OS peut purger le cache.
  • Offline ≠ données illimitées : stocker ce qui sert.
  • Synchronisation en background respectant les règles du chapitre 6.

9. Stores

9.1 Play Store (Android)

  • Compte développeur : 25 $ (one-shot).
  • Formats : AAB (Android App Bundle) obligatoire depuis 2021.
  • Tests : Play Console → Internal, Closed, Open testing.
  • Review : automatisée + humaine pour les apps sensibles (permissions).
  • Délai de publication : quelques heures à quelques jours.
  • Réglementations : déclaration des données, politique de confidentialité, SDK attestation (gestionnaire de consentement), cibles API (targetSdk).

9.2 App Store (iOS)

  • Compte développeur : 99 $/an (gratuit pour les orgs éducatives).
  • Formats : IPA signé, livré via Xcode/App Store Connect.
  • TestFlight : jusqu'à 10 000 testeurs, 90 jours par build.
  • Review : manuelle, règles strictes (Guidelines 4.x notamment). Délai : 24–48 h en moyenne, plus si litige.
  • App Privacy → « nutrition label » obligatoire.
  • Paiements : commission 15–30 % (réduite 15 % pour les petits business < 1 M$).

9.3 Checklist de publication

  • targetSdk/iOS deployment target à jour
  • Permissions justifiées dans le code et le store
  • Privacy manifest/nutrition label rempli
  • Icônes, screenshots, description multilingue
  • Test sur device réel (pas seulement émulateur)
  • Tests unitaires + UI verts
  • Gestion du crash (Crashlytics, Sentry, Datadog)
  • Rollout progressif (staged rollout / phased release)

9.4 Après publication

  • Monitoring : crash, ANR, Crashes (iOS), Network errors.
  • Feedback utilisateurs : notes, avis, réponses.
  • Mise à jour régulière : 2–4 semaines de cycle typique.

10. Résumé et checklist

10.1 Points clés

  • Le lifecycle est la pierre angulaire : chaque état a ses responsabilités.
  • Le thread principal ne se bloque jamais : jamais de réseau ni de calcul lourd.
  • La mémoire est limitée : l'OS tue plutôt que swap ; fuites = crash lents.
  • Material 3 et HIG dictent des comportements différents selon la plateforme.
  • L'accessibilité est un critère de qualité et une obligation légale.
  • Le background est contraint par l'OS : WorkManager, BGTask, push.
  • L'énergie se gère comme une ressource : mesures, regroupement, adaptivité.
  • L'offline demande une stratégie (cache, network-first, offline-first).
  • Le store impose des règles de review et de conformité.

10.2 Checklist

  • Je sais ordonner les états du lifecycle des 4 plateformes
  • Je sais expliquer le rôle du thread principal
  • Je sais identifier une fuite mémoire (ARC cycle / Activity leak)
  • Je connais les différences Material 3 / HIG
  • Je sais rendre un composant accessible (label, role, test)
  • Je sais planifier une tâche en arrière-plan sur chaque plateforme
  • Je connais les leviers de réduction de consommation batterie
  • Je peux choisir une stratégie offline pour un produit
  • Je connais le processus de publication Play Store / App Store

Prochain chapitre

02-Android-Natif : Android Studio, Gradle, Manifest, Activities & Fragments, ViewModel, resources, build variants.