Chapitre 4 Le modèle de composants 1
Plan du chapitre 4 Les composants fondamentaux : Activity, Service, BroadcastReceiver, ContentProvider Les activités (cycle de vie, navigation entre les activités, communication interactivités...) Les services (cycle de vie, tâches de fond...). Les types de services (locaux et distants) Le langage AIDL 2
Application android : les fondamentaux (1/3) Rappel :.apk= une application Android, une application Android est dans un.apk "The Android SDK tools compile the code along with any data and resource files into an Android package, an archive file with an.apk suffix. All the code in a single.apkfile is considered to be one application and is the file that Android-powered devices use to install the application." (*) L'environnement Android d'exécution est un système Linux multiutilisateur. Chaque application est exécutée sous un utilisateur différent source : (*) developer.android.com/guide/components/fundamentals.html 3
Application android : les fondamentaux (2/3) "By default, the system assigns each application a unique Linux user ID (the ID is used only by the system and is unknown to the application). The system sets permissions for all the files in an application so that only the user ID assigned to that application can access them. Each process has its own virtual machine (VM), so an application's code runs in isolation from other applications. By default, every application runs in its own Linux process. Android starts the process when any of the application's components need to be executed, then shuts down the process when it's no longer needed or when the system must recover memory for other applications." C'est clair, non? Bibliographie : http://developer.android.com/guide/components/fundamenta 4 ls.html
Application android : les fondamentaux (3/3) Cela dit, il est possible de faire en sorte que deux applications aient le même Linux User ID. Elles pourront alors partager les mêmes fichiers, s'exécuter dans le même process, partager la même VM Evidemment une application peut, si elle en a la permission, accéder aux données d'autres applications comme les contacts, les SMS, la SD card, la caméra, le réseau, etc. Bibliographie : http://developer.android.com/guide/components/fund amentals.html 5
Android = architecture de composants (rappel?) Attention composant = mot galvaudé Pour Android, les principales classes développées et les objets de cette classe sont des composants Composant = objet dont le cycle de vie, le lancement de certaines méthodes est pris en charge par l'environnement d'exécution = ce n'est pas l'utilisateur, ni le développeur qui décident quand certains codes, certains chargements sont lancés. C'est l'environnement d'exécution (= Android) => le développement doit suivre des règles de programmation : dériver de certaines classes, développer certaines méthodes, etc. = architecture de framework : cf. applet, servlet, EJB,... Les composants fondamentaux sont : les Activity, les Service, les BroadcastReceiver, les ContentProvider 6
Cycle de vie d'une Activity Lorsqu'un objet d'une classe Activityest créé, celui ci va passer dans différents états pendant sa vie Lorsqu'un objet d'une classe Activitypasse d'un état à un autre, l'environnement d'exécution Android, lance automatiquement certaines méthodes sur cette activité Au lancement de l'application (lors du clic sur son icône par exemple), une instance de l'activité principale (indiquée dans l'androidmanifest.xml) est construite par l'environnement d'exécution Android. Elle est lancée par un Intent d'action MAIN et de category LAUNCHER <activity android:name=".mainactivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> bibliographie : http://developer.android.com/training/basics/activitylifecycle/index.html 7
Cycle de vie d'une Activity L'automate (simplifié) du cycle de vie : la "step pyramid" : source : http://developer.android.com/training/basics/activitylifecycle/starting.html 8
Autre diagramme d'état d'une Activity Un diagramme similaire au précédent : Moins (ou plus) clair car des états ont été supprimés source : http://developer.android.com/refer ence/android/app/activity.html 9
Signification des états L'état Resumed est souvent appelé l'état Running Les états Created et Started sont dits transient, c'est à dire qu'on passe immédiatement de l'un à l'autre après exécution des méthodes de passage (oncreate(), onstart(), onresume()) Les états Resumed (= Running), Paused, Stopped sont dits static, c'est à dire qu'on peut y être pendant une certaine durée Dans l'état Resumed = Running, l'activité est en avant plan et l'utilisateur peut interagir avec Dans l'état Paused, l'activity est partiellement obscurcie par une autre activity. Dans cet état l'activity ne peut pas recevoir d'entrée utilisateur, ni exécuter du code Dans l'état Stopped, l'activity est complètement masquée (non visible à l'utilisateur). Elle est dite en arrière plan. L'objet activity existe toujours (et garde ses valeurs) mais ne peut pas exécuter de code 10
Passage dans les états Stopped et Started Par abus de langage, on identifie souvent une activité (une classe) avec l'objet qui a été créé à partir de cette activité. C'est le cas ci dessous ou activité = objet Si l'utilisateur fait une action qui démarre une nouvelle activité B, l'activité courante A passe dans l'état Stopped et la nouvelle activité B est créée et arrive à l'état Resumed. Par la suite, quand l'utilisateur appuie sur le bouton back, la première activité A passe dans l'état Started (puis l'état Resumed) et l'activité B passe dans l'état Stopped, puis dans l'état Destroyed => L'appui sur le bouton back amène l'activité en cours dans l'état Destroyed (eh oui) Quand l'utilisateur reçoit un appel téléphonique, l'activité courante passe dans l'état Stopped. Lorsque l'appel téléphonique est terminé, cette activité revient dans Started (puis l'état Resumed) 11
Le contenu des View de Stopped à Started Précisément : "When your activity is stopped, the Activity object is kept resident in memory and is recalled when the activity resumes. You don t need to re-initialize components that were created during any of the callback methods leading up to the Resumed state. The system also keeps track of the current state for each View in the layout, so if the user entered text into an EditText widget, that content is retained so you don't need to save and restore it." Bref on garde le contenu des View source : http://developer.android.com/training/basics/activitylifecycle/stopping.html#start 12
Destruction d'une Activity Une activité est détruite lorsque : l'utilisateur appui sur le bouton back l'application a lancé finish() sur l'activité l'activité était stoppée et l'environnement d'exécution a besoin de mémoire Une activité est détruite et recréée lorsque l'utilisateur change de mode d'affichage de portrait à paysage ou le contraire! "Caution: Your activity will be destroyed and recreated each time the user rotates the screen. When the screen changes orientation, the system destroys and recreates the foreground activity because the screen configuration has changed and your activity might need to load alternative resources (such as the layout)." source : http://developer.android.com/training/basics/activitylifecycle/recreating.html 13
Récupération après destruction Si l'activité a été détruite par appui sur le bouton back ou lancement de finish(), toutes les données de cette activité sont perdues : "When your activity is destroyed because the user presses Back or the activity finishes itself, the system's concept of that Activity instance is gone forever because the behavior indicates the activity is no longer needed" Si l'activité a été détruite par l'environnement d'exécution (du à des contraintes système), celui a sauvegardé les données de chaque Viewde l'activité (comme le texte écrit dans une EditText) dans un Bundle(= collection de paires clé String-valeur Object). Mais pour cela les View doivent avoir un attribut android:id Ainsi si une activité est détruite par l'environnement (et pas par une action de l'utilisateur) et recréée, l'état des View est restaurée source : http://developer.android.com/training/basics/activitylifecycle/recreating.html 14
Sauvegarde de données lors d'une destruction d'activité Pour sauvegarder des données supplémentaires, il faut utiliser la méthode protected void onsaveinstancestate (Bundle outstate). Cette méthode est appelée avant que l'activity soit détruite Par exemple : static final String STATE_SCORE = "playerscore"; static final String STATE_LEVEL = "playerlevel";... @Override public void onsaveinstancestate(bundle savedinstancestate) { // Save the user's current game state savedinstancestate.putint(state_score, mcurrentscore); savedinstancestate.putint(state_level, mcurrentlevel); } // Always call the superclass so it can save the view hierarchy state super.onsaveinstancestate(savedinstancestate); Remarque : il faut bien appeler super.onsaveinstancestate(savedinstancestate); 15
Récupération de données après une destruction d'activité Lorsque l'activité est recrée, les données sauvegardées par onsaveinstancestate (Bundle outstate)peuvent être récupérées par oncreate()et onrestoreinstancestate()qui ont, toutes deux, ce Bundle comme argument : public void onrestoreinstancestate(bundle savedinstancestate) { // Always call the superclass so it can restore the view hierarchy super.onrestoreinstancestate(savedinstancestate); } // Restore state members from saved instance mcurrentscore = savedinstancestate.getint(state_score); mcurrentlevel = savedinstancestate.getint(state_level); 16
Cycle de vie approfondie d'une Activity En fait le cycle de vie d'une activité est plutôt : 17
Démo du cycle de vie d'une Activity Démo à charger à partir de http://developer.android.com/trai ning/basics/activitylifecycle/index.html Voir exécution dans Travail, Ch4CycleVieActivityProjet Sachant que les événements les plus récents sont en premières lignes, que s'est il passé? Réponse : L'activité A a été lancée en premier, puis l'activité B (bouton Start B), puis un Dialog a été affiché (bouton Dialog) (B.onPause()) puis ce Dialog a été enlevé (B.onResume()) 18
Démo du cycle de vie d'une Activity : explication La classe StatusTrackercontient le nom des méthodes qui ont été lancées (dans List<String> mmethodlist) ainsi que le statut de chaque activité dans Map<String, String> mstatusmap, les clés étant les noms des activités, les valeurs leurs statuts A chaque fois qu'une activité change de statut, elle en informe le StatusTracker qui enrichit ces deux champs La méthode Utils.printStatus(...)met à jour les composants graphiques de l'activité principale et est appelée à chaque changement de statut de chaque activité ou dialogue 19
Fin 20