Principes d'application

applications Android sont écrites dans le langage de programmation Java -. compilé Le code Java ainsi que tous les fichiers de données et des ressources requises par l'application - est fourni par le AAPT outil dans un package Android, un fichier d'archive marquée par une apk. suffixe. Ce fichier est le véhicule pour la diffusion de l'application et l'installer sur les appareils mobiles, c'est le fichier de téléchargement pour les utilisateurs de leurs appareils. Tout le code dans un seul apk. fichier est considéré comme l'un demande.

À bien des égards, vit chaque application Android dans son propre monde:

  • Par défaut, chaque application s'exécute dans son propre processus Linux. Android commence le processus lorsque l'un quelconque d'application du code du doit être exécuté, et arrête le processus quand il n'est plus nécessaire et les ressources système sont requises par d'autres applications.
  • Chaque processus a sa propre machine virtuelle (VM), code d'application s'exécute alors dans l'isolement du code de toutes les autres applications.
  • Par défaut, chaque demande se voit attribuer un ID utilisateur unique Linux -. Autorisations sont définies de sorte de l'application que les fichiers ne sont visibles que pour cet utilisateur et uniquement à la demande elle-même même si il ya des façons de les exporter vers d'autres applications.

Il est possible de prendre des dispositions pour deux applications de partager le même ID utilisateur, auquel cas ils seront en mesure de voir les fichiers des autres. Pour économiser les ressources système, les applications avec le même ID peut également prendre des dispositions pour exécuter Linux dans le même processus, en partageant les mêmes VM.

Composants de l'application

Un élément central de Android est qu'une application peut utiliser des éléments d'autres applications (à condition que ces applications le permettent). Par exemple, si votre application a besoin d'afficher une liste déroulante des images et une autre application a mis au point un effet de défilement approprié et rendu accessible à d'autres, vous pouvez appeler sur cette molette pour faire le travail, plutôt que de développer votre propre. Doesn Votre demande " t intégrer le code de l'application ou lien vers elle. Plutôt, il commence simplement jusqu'à ce morceau de l'application d'autres lorsque le besoin s'en fait sentir.

Pour que cela fonctionne, le système doit être capable de démarrer un processus d'application lorsqu'une partie de celui-ci est nécessaire, et instancier des objets Java pour cette partie. Par conséquent, contrairement à la plupart des applications sur d'autres systèmes, les applications Android n'ont pas une seule entrée pour tout point de l'application (pas de main () la fonction, par exemple). Au contraire, ils ont essentielle composants que le système peut instancier et d'exécuter au besoin. Il existe quatre types de composants:

Activités
Une activité présente une interface visuelle pour une entreprise axée l'utilisateur peut effectuer. Par exemple, une activité peut présenter une liste d'éléments de menu les utilisateurs peuvent choisir ou il peut afficher des photos avec leurs légendes. Une application de messagerie texte peut avoir une activité qui affiche une liste de contacts pour envoyer des messages, une seconde activité pour écrire le message dans le contact choisi, et d'autres activités de revoir les anciens messages ou modifier les paramètres. Bien qu'ils travaillent ensemble pour former une interface utilisateur cohérente, chaque activité est indépendante des autres. Chacun est implémenté comme une sous-classe de l' activité de classe de base.

Une application pourrait consister en une seule activité ou, comme l'application de messagerie texte viens de mentionner, il peut contenir plusieurs. Quels sont les activités, et combien il y en dépend, bien sûr, sur l'application et sa conception. Typiquement, l'une des activités est marqué comme le premier qui doit être présenté à l'utilisateur lorsque l'application est lancée. Déménagement d'une activité à une autre se fait en ayant l'activité actuelle de lancer la suivante.

Chaque activité est proposée une fenêtre par défaut d'établir en règle générale, la fenêtre occupe tout l'écran, mais il pourrait être plus petit que l'écran et flotter au-dessus des autres fenêtres. Une activité peut également faire usage de fenêtres supplémentaires - par exemple, un pop-up de dialogue qui demande une réponse de l'utilisateur dans le milieu de l'activité, ou une fenêtre qui présente aux utilisateurs des informations vitales quand ils sélectionner un élément particulier à l'écran.

Le contenu visuel de la fenêtre est assurée par une hiérarchie de vues - les objets dérivés de la base Voir la classe. Chaque vue des contrôles rectangulaire espace particulier au sein de la fenêtre. point de vue des parents circonscrire et d'organiser la présentation de leurs enfants. Feuille d'avis (ceux qui sont au bas de la hiérarchie) tirer dans les rectangles qu'ils contrôlent et de répondre aux actions de l'utilisateur visant à cet espace. Ainsi, les vues sont où l'activité de l'interaction avec l'utilisateur prend place. Par exemple, une vue peut afficher une petite image et d'engager une action lorsque l'utilisateur tape cette image. Android a un certain nombre de faits vues prêt que vous pouvez utiliser - y compris les boutons, champs texte, les barres de défilement, des éléments de menu, les cases à cocher, et plus encore.

Une hiérarchie de la vue est placée dans l'activité de la fenêtre d'une par le Activity.setContentView () méthode. L' affichage du contenu est l'objet View à la racine de la hiérarchie. (Voir la séparer de l'interface utilisateur du document pour plus d'informations sur les points de vue et la hiérarchie.)

Services
Un service ne dispose pas d'une interface utilisateur visuelle, mais tourne plutôt à l'arrière-plan pour une période de temps indéfinie. Par exemple, un service pourrait jouer la musique de fond que l'utilisateur participe à d'autres questions, ou il peut récupérer les données sur le réseau ou de calculer quelque chose et donner le résultat des activités qui en ont besoin. Chaque service étend le service de classe de base.

Un premier exemple est un lecteur multimédia jouer des chansons à partir d'une liste de lecture. L'application Lecteur aurait probablement une ou plusieurs activités qui permettent à l'utilisateur de choisir des chansons et commencer à les jouer. Cependant, la lecture de la musique elle-même ne serait pas gérée par une activité parce que les utilisateurs s'attendent à la musique de continuer à jouer même après avoir quitté le lecteur et commencer quelque chose de différent. Pour la musique continue, l'activité Media Player pourrait lancer un service pour courir à l'arrière-plan. Le système serait alors maintenir le service de lecture de musique en cours d'exécution, même après l'activité qui a commencé il quitte l'écran.

Il est possible de se connecter à (lier) un service continu (et démarrer le service si ce n'est pas déjà fait). Une fois connecté, vous pouvez communiquer avec le service à travers une interface que le service expose. Pour le service de musique, cette interface pourrait permettre aux utilisateurs de faire une pause, rembobiner, arrêter et redémarrer la lecture.

Comme les activités et les autres composantes, les services s'exécutent dans le thread principal du processus de demande. Alors qu'ils ne bloque pas les autres composants ou l'interface utilisateur, ils ont souvent frayer un autre thread pour laborieuses tâches temps (comme la lecture de musique). Voir processus et les threads, plus tard.

Les récepteurs de radiodiffusion
Un récepteur de radiodiffusion est un élément qui ne fait rien, mais de recevoir et de réagir à diffuser des annonces. de nombreuses émissions provenant du code du système - par exemple, les annonces que le fuseau horaire a changé, que la batterie est faible, que la photo a été prise, ou que l'utilisateur a modifié une préférence de langue. Les applications peuvent aussi lancer des émissions - par exemple, de laisser d'autres applications sais que certaines données ont été téléchargées sur le périphérique et est disponible pour eux à utiliser.

Une application peut avoir n'importe quel nombre de récepteurs de radiodiffusion pour répondre à toutes les annonces qu'il juge importante. Tous les récepteurs étendre la BroadcastReceiver classe de base.

Les récepteurs de radiodiffusion ne pas afficher une interface utilisateur. Toutefois, ils peuvent démarrer une activité en réponse à l'information qu'ils reçoivent, ou ils peuvent utiliser les NotificationManager à alerter l'utilisateur. Les notifications peuvent obtenir l'attention de l'utilisateur de diverses manières - le clignotement du rétro-éclairage, le dispositif vibrant, jouer un son, et ainsi de suite. Ils accordent généralement une icône persistante dans la barre d'état, les utilisateurs peuvent ouvrir à faire passer le message.

Les fournisseurs de contenu
Un fournisseur de contenu rend un ensemble spécifique de d'autres applications de l'application de données disponibles. Les données peuvent être stockées dans le système de fichiers, une base de données SQLite, ou de toute autre manière qui fait sens. Le fournisseur de contenu étend la ContentProvider classe de base pour mettre en œuvre un ensemble standard de méthodes qui permettent d'autres applications pour récupérer et stocker des données de la type qu'il contrôle. Toutefois, les demandes ne sont pas appeler ces méthodes directement. Au contraire, ils utilisent un ContentResolver objet et appeler ses méthodes au lieu;. ContentResolver A peut parler à tout fournisseur de contenu, elle coopère avec le fournisseur pour gérer toute la communication interprocessus qui est impliqué.

Voir la distinctes fournisseurs de contenu du document pour plus d'informations sur l'utilisation de fournisseurs de contenu.

Chaque fois qu'il ya une demande qui devrait être géré par un composant particulier, Android permet de s'assurer que le processus de demande de la composante est en marche, il partir, si nécessaire, et que l'instance appropriée du composant est disponible, la création de l'instance si nécessaire.

Activation de composants: les intentions

Les fournisseurs de contenu sont activées quand ils sont visés par une demande d'un ContentResolver. Les trois autres éléments - les activités, les services et les récepteurs de radiodiffusion - sont activés par messages asynchrones appelé intentions. L'intention est une intention objet qui contient le contenu du message. Pour les activités et les services, il nomme les mesures qu'il est demandé et spécifie l'URI des données pour agir sur, entre autres. Par exemple, il peut transmettre une demande pour une activité de présenter une image à l'utilisateur ou de laisser l'utilisateur d'éditer du texte. Pour les récepteurs de radiodiffusion, les noms des objets intention de l'action étant annoncé. Par exemple, il pourrait annoncer aux parties intéressées que le bouton de la caméra a été enfoncée.

Il existe des méthodes distinctes pour activer chaque type de composant:

  • Une activité est lancé (ou donné quelque chose de nouveau à faire) en passant un objet intention de Context.startActivity () ou Activity.startActivityForResult (). L'activité répondant peut comparer à l'objectif initial qui a provoqué ce qui doit être lancé en appelant sa getIntent () méthode. Android appels de l'activité onNewIntent () méthode pour lui passer les intentions ultérieures.

    Une activité commence souvent la suivante. Si elle s'attend à un résultat de retour de l'activité ça commence, il appelle startActivityForResult () au lieu de startActivity (). Par exemple, si elle commence une activité qui permet à l'utilisateur de sélectionner une photo, il peut s'attendre à être retourné la photo choisie. Le résultat est retourné dans un objet intention qui est transmis à l'activité appelant onActivityResult () méthode.

  • Un service est démarré (ou de nouvelles instructions sont données pour un service continu) en passant un objet intention de Context.startService (). Android appelle le service de onStart () la méthode et lui passe l'objet d'intention.

    De même, l'intention peut être passé à Context.bindService () pour établir une connexion permanente entre le composant appelant et un service cible. Le service reçoit l'objet d'une intention onBind () appel. (Si le service n'est pas déjà en cours d'exécution, bindService () peut éventuellement mettre en marche.) Par exemple, une activité peut établir une connexion avec le service de lecture de musique mentionné plus tôt de sorte qu'il peut fournir à l'utilisateur les moyens (une interface utilisateur) pour contrôler la lecture. L'activité pourrait appeler bindService () de mettre en place cet égard, et ensuite appeler les méthodes définies par le service d'affecter la lecture.

    Une section plus tard, les appels de procédure à distance, a plus de détails sur la liaison à un service.

  • Une application peut ouvrir une émission en passant un objet intention de méthodes comme Context.sendBroadcast (), Context.sendOrderedBroadcast (), et Context.sendStickyBroadcast () dans aucune de leurs variations. Android offre l'intention de tous les récepteurs de radiodiffusion intéressés en appelant leur OnReceive () méthodes.

Pour en savoir plus sur l'intention messages, voir l'article séparé, intentions et l'intention Filtres.

Arrêt de composants

Un fournisseur de contenu est active uniquement lorsque c'est répondre à une demande d'un ContentResolver. Et un récepteur de radiodiffusion est active uniquement lorsque c'est répondre à un message diffusé. Il n'y a donc pas nécessaire de fermer explicitement ces composants.

Activités, d'autre part, de fournir l'interface utilisateur. Ils sont dans une course-longue conversation avec l'utilisateur et peut rester actif, même en cas d'inactivité, aussi longtemps que la conversation continue. De même, les services peuvent aussi continuer à s'exécuter pendant une longue période. Ainsi, Android a des méthodes pour arrêter les activités et les services d'une manière ordonnée:

  • Une activité peut être arrêté en appelant sa finish () méthode. Une activité peut arrêter une autre activité (on l'a commencé avec startActivityForResult ()) en appelant finishActivity ().
  • Un service peut être arrêté en appelant sa stopSelf () la méthode, ou en appelant Context.stopService ().

Les composants peuvent également être arrêté par le système quand ils ne sont plus utilisés ou lorsque Android doit récupérer de la mémoire pour plus de composants actifs. Une section plus tard, des cycles de vie de composants, discute de cette possibilité et ses ramifications dans plus de détails.

Le fichier manifeste

Avant Android pouvez commencer un composant d'application, il doit apprendre que le composant existe. Par conséquent, les applications de déclarer leurs composants dans un fichier manifeste qui est livré dans l'emballage Android, l' APK. fichier qui contient également l'application du code de l', des fichiers et des ressources.

Le manifeste est un fichier XML structuré et est toujours nommé AndroidManifest.xml pour toutes les applications. Il fait un certain nombre de choses en plus de déclarer l'application des composants, tels que les noms des bibliothèques de l'application doit être lié à (en dehors de l'Android bibliothèque par défaut) et d'identifier toutes les autorisations de l'application s'attend à être accordée.

Mais la tâche principale du manifeste est d'informer Android sur l'application de composants de l'. Par exemple, une activité pourrait être déclaré comme suit:

<?xml version="1.0" encodage="utf-8"?>
<manifeste . . . >
   
<Application . . . >
       
l'activité < android: nom="com.example.project.FreneticActivity"
                 
Android: icon="@ étirable / small_pic.png"
                 
Android: label="@ string / freneticLabel"
                  . . .  
>
       
</ Activité>
        . . .
   
</ Application>
</ manifest>

Le nom de l'attribut de la <activity> noms élément d'activité sous-classe qui implémente l'activité. L' icône et l'étiquette attributs point aux fichiers de ressources contenant une icône et l'étiquette qui peut être affiché aux utilisateurs de représenter l'activité.

Les autres composants sont déclarés d'une manière similaire - <service> éléments pour les services, <destinataire> éléments pour récepteurs de radiodiffusion, et <provider> éléments pour les fournisseurs de contenu. , Des services et des fournisseurs de contenu activités qui ne sont pas déclarés dans le manifeste ne sont pas visibles par le système et sont par conséquent ne jamais courir. Cependant, les récepteurs de radiodiffusion peuvent être déclarées dans le manifeste, ou ils peuvent être créés dynamiquement dans le code (comme BroadcastReceiver objets) et enregistré avec le système en appelant Context.registerReceiver ().

Pour en savoir plus sur la façon de structurer un fichier manifeste pour votre application, consultez le fichier AndroidManifest.xml.

Intention filtres

Un objet peut intention explicitement le nom d'un composant cible. Si c'est le cas, Android constate que le composant (sur la base des déclarations dans le fichier manifeste) et l'active. Mais si une cible n'est pas explicitement nommé, Android doit localiser les meilleurs composants pour répondre à l'intention. Il le fait en comparant l'objet à l'intention des filtres intention de cibles potentielles. L'intention du constituant A filtres informer Android de l'sortes d'intentions le composant est capable de gérer. Comme d'autres informations essentielles sur le composant, ils sont déclarés dans le fichier manifeste. Voici une extension de l'exemple précédent qui ajoute deux filtres intention de l'activité:

<?xml version="1.0" encodage="utf-8"?>
<manifeste . . . >
   
<Application . . . >
       
l'activité < android: nom="com.example.project.FreneticActivity"
                 
Android: icon="@ étirable / small_pic.png"
                 
Android: label="@ string / freneticLabel"
                  . . .  
>
           
<Intention de filtre . . . >
               
<Action android: nom="android.intent.action.MAIN" />
               
<Catégorie android: nom="android.intent.category.LAUNCHER" />
           
</ Intention de filtre>
           
<Intention de filtre . . . >
               
<Action android: nom="com.example.project.BOUNCE" />
               
<Données android: mimeType="image / jpeg" />
               
<Catégorie android: nom="android.intent.category.DEFAULT" />
           
</ Intention de filtre>
       
</ Activité>
        . . .
   
</ Application>
</ manifest>

Le premier filtre dans l'exemple - la combinaison de l'action "android.intent.action.MAIN»et la catégorie"android.intent.category.LAUNCHER"- est une commune en. Elle marque l'activité comme celle qui doit être représentée le lanceur d'application, la liste des utilisateurs des applications d'écran permet de lancer sur le périphérique. En d'autres termes, l'activité est le point d'entrée pour l'application, dont la première serait utilisateurs voient quand ils choisir l'application dans le lanceur.

Le second filtre déclare une action que l'activité peut effectuer sur un type particulier de données.

Un élément peut avoir n'importe quel nombre de filtres intention, chacun déclarant un ensemble différent de fonctionnalités. Si elle n'a pas de filtres, il peut être activé que par des intentions qui explicitement le nom de l'élément en tant que cible.

Pour un récepteur de radiodiffusion qui est créé et enregistré dans le code, l'intention de filtre est instancié directement comme IntentFilter objet. Tous les autres filtres sont mis en place dans le manifeste.

Pour en savoir plus sur les filtres intention, voir un document distinct, intentions et des filtres intention.

Activités et tâches

Tel que mentionné précédemment, une activité peut commencer une autre, y compris celle qui est définie dans une autre application. Supposons, par exemple, que vous souhaitez pour permettre aux utilisateurs d'afficher une carte de rue de certains endroit. Il ya déjà une activité qui peut le faire, afin que tous les besoins de votre activité à faire est de mettre ensemble un objet intention avec les renseignements requis et le transmettre à startActivity (). La visualisation cartographique affiche la carte. Lorsque l'utilisateur appuie sur la touche BACK, votre activité réapparaît à l'écran.

Pour l'utilisateur, il semble comme si le spectateur carte fait partie de la même application que votre activité, même si elle a été définie dans une autre application et exécute en application du processus qui. Android maintient cette expérience utilisateur en gardant les deux activités dans la même tâche. Autrement dit, une tâche est ce que l'utilisateur l'expérience comme une «application». Il s'agit d'un groupe d'activités connexes, disposés en pile. L'activité des racines de la pile est celle qui a commencé la tâche -, il s'agit d'une activité de l'utilisateur sélectionné dans l'application. Lanceur généralement l'activité au sommet de la pile est celui qui est en cours d'exécution - celui qui fait l'objet d'actions de l'utilisateur . Quand on commence une autre activité, la nouvelle activité est poussé sur la pile, elle devient l'activité en cours pile. Précédentes L'activité reste dans le. Lorsque l'utilisateur appuie sur la touche BACK, l'activité en cours est relevé de la pile, et le précédent reprend que l'activité en cours.

La pile contient des objets, si une tâche a plus d'une instance de la sous-classe même activité ouverte - visualisation de cartes multiples, par exemple - la pile a une entrée séparée pour chaque instance. Activités de la pile ne sont jamais réarrangé, seulement poussé et maïs.

Une tâche est un empilement d'activités, et non pas une classe ou d'un élément dans le fichier manifeste. Il n'y a donc aucun moyen de définir des valeurs pour une tâche de manière indépendante de ses activités. Les valeurs de la tâche dans son ensemble sont définies dans l'activité des racines. Par exemple, la section suivante parlera de la «affinité d'une tâche"; cette valeur est lue à partir de l'affinité pour définir l'activité de la racine de la tâche.

Toutes les activités dans une tâche de se déplacer comme un tout. L'ensemble de la tâche (l'activité ensemble de la pile) peut être amené au premier plan ou envoyés à l'arrière-plan -. Supposons, par exemple, que la tâche actuelle a quatre activités dans sa pile trois titre de l'activité actuelle. L'utilisateur appuie sur la touche HOME, va au lanceur d'application, et choisit une nouvelle demande (en fait, une nouvelle tâche). La tâche en cours passe en arrière-plan et l'activité des racines de la nouvelle tâche est affichée. Puis, après une courte période , l'utilisateur remonte à l'écran d'accueil et sélectionne à nouveau la demande antérieure (la tâche précédente). Cette tâche, avec les quatre activités de la pile, se présente. Lorsque l'utilisateur appuie sur la touche BACK, l'écran n'affiche pas l'activité de l'utilisateur vient de quitter (l'activité des racines de la tâche précédente). Au contraire, l'activité sur le haut de la pile est enlevée et l'activité précédente dans la même tâche est affichée.

Le comportement vient d'être décrit est le comportement par défaut pour les activités et tâches. Mais il ya des façons de modifier presque tous les aspects de celui-ci. L'association des activités avec les tâches, et le comportement d'une activité dans une tâche, est contrôlée par l'interaction entre les drapeaux dans l'objet de l'intention qui a commencé l'activité et attributs définis dans l'activité de <activity> élément dans le manifeste. Les deux demandeur et le défendeur ont leur mot à dire dans ce qui se passe.

À cet égard, les drapeaux intention principaux sont:

FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_SINGLE_TOP

Le principal <activity> attributs sont les suivants:

taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch

Les sections suivantes décrivent ce que certains de ces indicateurs et les attributs font, comment ils interagissent, et quels facteurs régissent leur utilisation.

Les affinités et les nouvelles tâches

Par défaut, toutes les activités dans une application ont une affinité pour l'autre - qui est, il ya une préférence pour tous d'appartenir à la même tâche. Toutefois, une affinité unique peut être fixé pour chaque activité avec les taskAffinity attribut de la <activity> élément. Les activités définies dans les différentes applications peuvent partager une affinité, ou d'activités définies dans la même application peut être attribué des affinités différentes. L'affinité entre en jeu dans deux cas: Lorsque l'objet d'intention qui lance une activité contient les FLAG_ACTIVITY_NEW_TASK drapeau, et quand une activité a ses allowTaskReparenting attribut à "true".

Le FLAG_ACTIVITY_NEW_TASK drapeau
Comme indiqué précédemment, une nouvelle activité est, par défaut, se lance dans la tâche de l'activité qui a appelé startActivity (). Il est poussé sur la même pile que l'appelant. Toutefois, si l'intention objet passé à startActivity () contient le FLAG_ACTIVITY_NEW_TASK pavillon, le système recherche une tâche différente à la maison de la nouvelle activité. Souvent, comme le nom du drapeau l'indique, c'est une nouvelle tâche. Toutefois, il n'a pas à être. S'il ya déjà une tâche existante avec la même affinité que la nouvelle activité, l'activité est lancé dans cette tâche. Sinon, il commence une nouvelle tâche.
Le allowTaskReparenting attribut
Si une activité a ses allowTaskReparenting attribut de "vrai", il peut se déplacer de la tâche démarre en à la tâche qu'il a une affinité pour cette tâche lorsque vient au premier plan. Par exemple, supposons qu'une activité que les rapports des conditions météorologiques dans certaines villes est définie dans le cadre d'une demande de Voyage. Il a la même affinité que d'autres activités dans la même application (l'affinité par défaut) et il permet de re-maternage. Un de vos activités commence le journaliste météo, de sorte qu'il appartient d'abord à la même tâche que votre activité. Toutefois, lorsque l'application Voyage prochaine se présente, le journaliste météo seront réaffectés et affiché dans cette tâche.

Si un apk. fichier contient plus d'une "application" de l'utilisateur point de vue, vous voudrez probablement à attribuer des affinités différentes pour les activités associées à chacun d'eux.

Lancement modes

Il ya quatre modes de lancement différents qui peuvent être assignées à un <activity> élément launchMode attribut:

"standard"(le mode par défaut)
"singleTop"
"singleTask"
"singleInstance"

Les modes diffèrent les uns des autres sur ces quatre points:

  • Quel est le rôle tiendra l'activité qui répond à l'intention. Pour le "standard"et"singleTop"modes, c'est la tâche que l'origine de l'intention (et a appelé startActivity ()) - sauf si l'objet intention contient les FLAG_ACTIVITY_NEW_TASK . drapeau Dans ce cas, , une tâche différente est choisie comme décrit dans la section précédente, affinités et les nouvelles tâches.

    En revanche, le "singleTask"et"singleInstance"modes marque activités qui sont toujours à la racine d'une tâche. Ils définissent une tâche; ils ne sont jamais lancés dans une autre tâche.

  • S'il peut y avoir plusieurs instances de l'activité. Un "standard"ou"singleTop"activité peut être instancié plusieurs fois. Ils peuvent appartenir à des tâches multiples, et une tâche donnée peut avoir plusieurs instances d'une même activité.

    En revanche, "singleTask"et"singleInstance"les activités sont limitées à une seule instance. Étant donné que ces activités sont à l'origine d'une tâche, cette limitation signifie qu'il n'y a jamais qu'une seule instance de la tâche sur le périphérique à un moment donné.

  • Que l'instance peut avoir d'autres activités dans sa tâche. A "singleInstance«activité représente à elle seule la seule activité dans sa tâche. Si elle commence une autre activité, cette activité sera lancé dans une tâche différente quel que soit son mode de lancement - comme si FLAG_ACTIVITY_NEW_TASK a été dans l'intention. Dans tous les autres égards, le «singleInstance"mode est identique à"singleTask".

    Les trois autres modes permettent de multiples activités d'appartenir à la tâche. A "singleTask«activité sera toujours l'activité des racines de la tâche, mais il peut commencer à d'autres activités qui seront affectés à sa tâche. Les cas de "standard"et"singleTop"activités peuvent apparaître n'importe où dans une pile.

  • Que ce soit une nouvelle instance de la classe sera lancée pour gérer une nouvelle intention. Pour la valeur par défaut "standard"mode, une nouvelle instance est créée pour répondre à chaque nouvelle intention. Chaque instance gère un seul but. Pour les "singleTopmode, une instance existante de la classe est ré-utilisé pour gérer une intention nouvelle si elle réside au sommet de l'activité pile de la tâche cible. Si elle ne réside pas au top, il n'est pas réutilisé. Au lieu de cela, une nouvelle instance est créée pour la nouvelle intention et poussé sur la pile.

    Par exemple, supposons que la tâche de l'activité d'une pile constituée de l'activité des racines Une des activités B, C, D et sur le dessus dans cet ordre, si la pile est ABCD. L'intention arrive pour une activité de type D. Si D est la valeur par défaut "standardlancer le mode ", une nouvelle instance de la classe est lancé et la pile devient ABCDD. Toutefois, si D's mode de lancement est"singleTop", l'instance existante est devrait pouvoir traiter l'intention de nouveaux (puisque c'est au sommet de la pile) et la pile reste ABCD.

    Si, d'autre part, l'intention à l'arrivée est pour une activité de type B, une nouvelle instance de B sera lancé, peu importe si le mode B est "standard"ou"singleTop"(puisque B n'est pas au sommet de la pile ), de sorte que la pile résultante serait ABCDB.

    Comme indiqué plus haut, il n'y a jamais plus d'une instance d'un "singleTask»ou«singleInstance"l'activité, de sorte que l'instance est prévu pour traiter toutes les intentions de nouvelles. Un "singleInstance"activité est toujours en haut de la pile (car elle est la seule activité à la tâche), il est donc toujours en mesure de traiter l'intention. Cependant, un «singleTask"activité peut ou peut ne pas avoir d'autres activités au-dessus de la pile. Si c'est le cas, il n'est pas en mesure de traiter l'intention, et l'intention est tombé. (Même si l'intention est tombé, son arrivée aurait causé la tâche à venir au premier plan, où il resterait.)

Quand une activité existante est chargé d'une nouvelle intention, l'objet intention est passé à l'activité dans un onNewIntent () appel. (L'objet que l'intention à l'origine a commencé l'activité peut être récupérée en appelant getIntent ().)

Notez que lorsque une nouvelle instance d'une activité est créé pour gérer une nouvelle intention, l'utilisateur peut toujours appuyer sur la touche BACK pour revenir à l'état précédent (à l'activité précédente). Mais quand une instance existante d'une activité poignées une nouvelle intention, l'utilisateur ne peut pas appuyer sur la touche BACK pour revenir à ce que cette instance a été fait avant l'arrivée de la nouvelle intention.

Pour en savoir plus sur les modes de lancement, voir la description de la <activity> élément.

Effacement de la pile

Si l'utilisateur quitte une tâche pendant une longue période, le système efface la tâche de toutes les activités, sauf l'activité des racines. Lorsque l'utilisateur revient à la tâche une fois, c'est que l'utilisateur a laissé, sauf que seul l'activité initiale est présent. L'idée est que, après un certain temps, les utilisateurs auront probablement abandonné ce qu'ils faisaient avant et reviennent à la tâche pour commencer quelque chose de nouveau.

C'est la valeur par défaut. Il ya quelques attributs activité qui peut être utilisé pour contrôler ce comportement et le modifier:

Le alwaysRetainTaskState attribut
Si cet attribut est réglé sur "true"dans l'activité des racines d'une tâche, le comportement par défaut vient d'être décrit n'est pas le cas. La tâche conserve toutes les activités dans sa pile, même après une longue période.
Le clearTaskOnLaunch attribut
Si cet attribut est réglé sur "true"dans l'activité des racines d'une tâche, la pile est autorisé à descendre à l'activité des racines lorsque l'utilisateur quitte la tâche et y retourne. En d'autres termes, il est à l'opposé de alwaysRetainTaskState. L'utilisateur revient toujours à la tâche dans son état initial, même après une absence momentanée.
Le finishOnTaskLaunch attribut
Cet attribut est comme clearTaskOnLaunch, mais il fonctionne sur une seule activité, pas une tâche complète. Et il peut causer toute activité de s'en aller, y compris l'activité des racines. Quand il est réglé sur "true", l'activité continue de faire partie de la tâche que pour la session en cours. Si l'utilisateur quitte et retourne ensuite à la tâche, il n'est plus présente.

Il ya un autre moyen de forcer les activités à être retiré de la pile. Si un objet intention comprend la FLAG_ACTIVITY_CLEAR_TOP drapeau, et la tâche cible a déjà une instance du type d'activité qui doit gérer l'intention dans sa pile, toutes les activités ci-dessus cette instance sont dissipé alors qu'il se trouve au sommet de la pile et peut répondre à l'intention. Si le mode de lancement de l'activité désignée est "standard", il sera lui aussi retiré de la pile, et une nouvelle instance sera lancée pour gérer l'intention entrants. C'est parce que une nouvelle instance est toujours créée pour une nouvelle intention lorsque le mode de lancement est "standard".

FLAG_ACTIVITY_CLEAR_TOP est le plus souvent utilisé en conjonction avec FLAG_ACTIVITY_NEW_TASK. Lorsqu'ils sont utilisés ensemble, ces indicateurs sont un moyen de localiser une activité existante dans une autre tâche et le mettre dans une position où il peut répondre à l'intention.

À partir de tâches

Une activité est mis en place comme point d'entrée pour une tâche en lui donnant une intention filtre avec "android.intent.action.MAIN"que l'action déterminée et"android.intent.category.LAUNCHER"comme catégorie spécifique. (Il ya un exemple de ce type de filtre dans la première intention Filtres section.) Un filtre de ce type entraîne une icône et une étiquette pour l'activité qui sera affiché dans le lanceur d'application, en donnant aux utilisateurs un moyen à la fois pour lancer la tâche et de revenir lui à tout moment après qu'il a été lancé.

Cette deuxième possibilité est important: les utilisateurs doivent être en mesure de laisser une tâche, puis y revenir plus tard. Pour cette raison, les deux modes de lancement que les activités de la marque, comme toujours lancement d'une mission, "singleTask"et"singleInstance", devrait être utilisée que lorsque l'activité a un MAIN et LANCEUR filtre. Imaginez, par exemple, ce qui pourrait arriver si le filtre est manquant: L'intention lance un "singleTask"l'activité, le lancement d'une nouvelle tâche, et l'utilisateur passe un certain temps de travail dans cette tâche. L'utilisateur appuie ensuite sur la touche HOME. La tâche est maintenant classés derrière et caché par l'écran d'accueil. Et, parce qu'il n'est pas représenté dans le lanceur d'application, l'utilisateur n'a aucun moyen d'y revenir.

Une difficulté similaire assiste à la FLAG_ACTIVITY_NEW_TASK pavillon. Si cette option provoque une activité pour commencer une nouvelle tâche et l'utilisateur appuie sur la touche HOME pour sortir, il doit y avoir un moyen pour l'utilisateur de naviguer de retour à nouveau. Certaines entités (telles que le gestionnaire de notification) toujours débuter les activités à une tâche externe, jamais dans le cadre de leurs propres, de sorte qu'ils ont toujours mis FLAG_ACTIVITY_NEW_TASK au niveau des intentions, ils passent à startActivity (). Si vous avez une activité qui peut être invoquée par une entité externe qui pourraient utiliser cet indicateur, veiller à ce que l'utilisateur dispose d'un moyen indépendant de revenir à la tâche qui a commencé.

Pour les cas où vous ne voulez pas que l'utilisateur soit en mesure de retourner à une activité, définir les <activity> élément finishOnTaskLaunch à "true". Voir compensation de la pile, plus tôt.

Processus et les threads

Lorsque la première application de composants une doit être exécuté, Android commence un processus Linux pour cela avec un seul thread d'exécution. Par défaut, tous les composants de l'application d'exécution dans ce processus et thread.

Cependant, vous pouvez organiser des composants pour courir à d'autres processus, et vous pouvez lancer des threads supplémentaires pour tout processus.

Processus

Le processus par lequel un composant s'exécute est contrôlé par le fichier de manifeste -. Les éléments composant <activity>, <service>, <destinataire>, et <provider> - ont chacun un processus attribut qui permet de spécifier un processus où ce composant doit être exécuté. Ces attributs peuvent être définies de sorte que chaque composant s'exécute dans son propre processus, ou que quelque part les composants d'un processus alors que d'autres n'ont pas. Ils peuvent également être réglé de telle manière que les composants de différentes applications s'exécutent dans le processus même - pour autant que les applications partagent le même ID utilisateur Linux et sont signés par les mêmes autorités le. <application> élément a aussi un processus d' attribut, pour le réglage par défaut valeur qui s'applique à tous les composants.

Tous les composants sont instanciés dans le thread principal du processus spécifié, et le système d'appels à la composante sont expédiés à partir de ce thread. threads séparés ne sont pas créés pour chaque instance. Par conséquent, les méthodes qui répondent à ces appels - des méthodes comme View.onKeyDown () que les actions de l'utilisateur du rapport et les notifications du cycle de vie discuté plus tard dans la composante des cycles de vie de l'article - toujours exécutées dans le thread principal du processus. Cela signifie qu'aucun élément doit effectuer à long ou des opérations de blocage (tels que des opérations de réseau ou de boucles de calcul) lorsqu'il est appelé par le système, car cela bloquerait tous les autres composants aussi dans le processus. Vous pouvez lancer des threads séparés pour des opérations longues, comme on le verra dans les discussions, à côté.

Android peut décider d'arrêter un processus à un moment donné, lorsque la mémoire est faible et nécessaire par d'autres procédés qui sont plus immédiatement au service de l'utilisateur. composants de l'application en cours d'exécution dans le processus sont donc détruits. Un processus est redémarré pour que les composants quand il ya encore du travail pour eux de le faire.

En décidant de mettre fin à des processus qui, Android pèse leur importance relative pour l'utilisateur. Par exemple, il s'arrête plus facilement un processus avec des activités qui ne sont plus visibles sur l'écran d'un processus avec les activités visibles. La décision de mettre fin à un processus, donc, dépend de l'état des composants en cours d'exécution dans ce processus. Ces Etats sont l'objet d'un article plus tard, des cycles de vie de composants.

Sujets

Même si vous pouvez limiter votre demande à un seul processus, il y aura probablement des moments où vous aurez besoin de lancer un thread pour effectuer un travail de fond. Depuis l'interface utilisateur doit toujours être prompt à réagir aux actions des utilisateurs, le fil qui héberge une activité ne devrait pas également l'hôte consommatrices de temps comme les opérations de téléchargements réseau. Tout ce qui ne peut être exécuté rapidement doit être attribué à un thread différent.

Les threads sont créés dans le code en utilisant la norme Java Thread objets. Android fournit un certain nombre de classes de commodité pour la gestion des threads - Looper pour exécuter une boucle de message dans un thread, gestionnaire pour le traitement des messages, et HandlerThread pour mettre en place un fil avec une boucle de message.

appels de procédure distante

Android a un mécanisme léger pour les appels de procédure distante (RPC) - où une méthode est appelée localement, mais l'exécution à distance (dans un autre processus), avec un résultat retourné à l'appelant pour. Cela implique la décomposition procédé à l'appel et malgré toutes ses données un niveau le système d'exploitation peut comprendre, de le transmettre à partir du processus local et l'adresse de l'espace au processus distant et l'espace d'adressage, et de remonter et de rejouer l'appel il. Les valeurs de retour doivent être transmises dans la direction opposée. Android fournit tout le code pour faire ce travail, de sorte que vous puissiez vous concentrer sur la définition et la mise en œuvre de la RPC se interface.

Une interface RPC peut comprendre que des méthodes. Par défaut, toutes les méthodes sont exécutées de manière synchrone (les blocs méthode locale jusqu'à la fin du procédé à distance), même s'il n'ya pas de valeur de retour.

En bref, le mécanisme fonctionne comme suit: Vous souhaitez commencer par déclarer l'interface RPC que vous souhaitez mettre en œuvre l'aide d'un simple IDL (Interface Definition Language). De cette déclaration, le AIDL outil génère une définition de l'interface Java qui doit être mis à disposition à la fois le local et le processus distant. Il contient deux classe interne, comme le montre le diagramme suivant:

RPC mechanism.

Les classes internes ont tout le code nécessaire pour administrer les appels de procédure distante pour l'interface que vous avez déclaré à l'IDL. Les deux classes internes mettre en œuvre les IBinder interface. L'un d'eux est utilisé localement et en interne par le système, le code que vous écrivez peut ignorer l'. L'autre, appelé Stub, s'étend Binder classe. En plus de code interne pour faire appliquer les appels de la CIB, il contient des déclarations pour les méthodes dans l'interface RPC que vous avez déclarés. Vous sous-classe Stub à mettre en œuvre ces méthodes, comme indiqué dans le schéma.

En règle générale, le processus distant serait géré par un service (car un service peut informer le système sur le processus et ses connexions à d'autres processus). Il aurait à la fois le fichier d'interface générée par le AIDL outil et la sous-classe Stub mise en œuvre des méthodes RPC. Les clients du service aurait uniquement le fichier interface générée par le AIDL outil.

Voici comment une connexion entre un service et ses clients est mis en place:

  • Les clients du service (sur le côté local) mettrait en oeuvre onServiceConnected () et onServiceDisconnected () méthodes afin qu'ils puissent être prévenu lorsque une connexion réussie au service à distance est établie, et quand il s'en va. Ils seraient alors appel bindService () pour configurer la connexion.
  • Le service de onBind () méthode serait mis en œuvre pour accepter ou rejeter la connexion, en fonction de l'intention qu'il reçoit (l'intention passé à bindService ()). Si la connexion est acceptée, elle retourne une instance de la sous-classe Stub.
  • Si le service accepte la connexion, Android appels du client onServiceConnected () la méthode et lui passe un objet IBinder, un indicateur de la sous-classe Stub géré par le service. Grâce à la procuration, le client peut faire des appels sur le service distant.

Cette brève description omet certains détails du mécanisme de RPC. Pour plus d'informations, consultez Conception d'une interface distante avec AIDL et le IBinder description de la classe.

méthodes thread-safe

Dans plusieurs contextes, les méthodes que vous mettre en œuvre peuvent être appelées à partir de plusieurs threads, et doit donc être écrit pour être thread-safe.

Ceci est surtout vrai pour les méthodes qui peuvent être appelés à distance - dans le RPC discuté mécanisme dans le précédent. Article comme Lors d'un appel sur un procédé mis en œuvre dans un objet IBinder son origine dans le même processus que le IBinder, la méthode est exécutée dans les années appelant thread. Toutefois, lorsque l'appel provient d'un autre processus, la méthode est exécutée dans un thread choisi à partir d'un pool de threads qui Android maintient dans le même processus que le IBinder, ce n'est pas exécutée dans le thread principal du processus. Par exemple, alors que d'un service onBind () la méthode doit être appelé depuis le thread principal de service du processus de la, les méthodes mises en œuvre dans l'objet qui onBind () retourne (par exemple, une sous-classe stub qui implémente les méthodes RPC) serait appelée à partir de fils de la piscine. Comme les services peuvent avoir plus d'un client, plus d'un pool de threads peut engager la IBinder même méthode, en même temps. IBinder méthodes doivent donc être mises en œuvre pour être thread-safe.

De même, un fournisseur de contenu peut recevoir des données qui proviennent des demandes dans d'autres procédés. Bien que les classes et ContentResolver ContentProvider masquer les détails de la façon dont la communication interprocessus est géré, les méthodes ContentProvider qui répondent à ces demandes - les méthodes query (), insert (), delete (), update (), et getType () - sont appelés à partir d'un pool de threads dans le contenu du fournisseur de processus de l', pas le thread principal du processus. Étant donné que ces méthodes peuvent être appelées à partir de n'importe quel nombre de threads en même temps, elles doivent également être mises en œuvre pour être thread-safe.

Cycles de vie des composants

composants de l'application ont un cycle de vie - un début quand Android instancie les intentions de répondre à travers un fin lorsque les cas sont détruits. Entre les deux, ils peuvent parfois être actif ou inactif, ou, dans le cas d'activités, visible à l'utilisateur ou invisible. Cette section traite des cycles de vie des activités, services, et les récepteurs de radiodiffusion - y compris le stipule qu'ils peuvent être dans le cours de leur vie, les méthodes qui vous informera des transitions entre les états, et l'effet de ces Etats sur la possibilité que le processus qui les accueillent pourrait être résilié et les instances détruits.

Activité du cycle de vie

Une activité a essentiellement trois états:

  • Il est actif ou en cours d'exécution quand il est au premier plan de l'écran (en haut de la pile pour l'activité de la tâche en cours). C'est l'activité qui fait l'objet d'actions de l'utilisateur.
  • Il est en pause si elle a perdu le focus, mais est encore visible à l'utilisateur. C'est, une autre activité se situe au-dessus de celui-ci et que l'activité est transparent ou ne couvre pas le plein écran, de sorte que certaines des activités en pause peut montrer à travers . Une pause activité est tout à fait vivants (il conserve tous les membres et les informations d'état et demeure attaché au gestionnaire de fenêtres), mais peuvent être tués par le système dans des situations extrêmes peu de mémoire.

  • Il est arrêté si elle est complètement obscurcie par une autre activité. Il conserve toutes les informations d'état et membre. Toutefois, il n'est plus visible à l'utilisateur pour sa fenêtre est caché et il sera souvent tués par le système lorsque la mémoire est nécessaire ailleurs.

Si une activité est interrompue ou arrêtée, le système peut tomber de la mémoire, soit en lui demandant de terminer (en appelant sa finish () la méthode), ou tout simplement tuer le processus. Quand il est à nouveau affichée à l'utilisateur, il doit être complètement renouvelées et restauré à son état précédent.

Comme une activité transitions d'un état à état, il est avisé du changement par les appels à la protection méthodes suivantes:

onCreate void (Bundle savedInstanceState)
onStart void ()
onRestart void ()
onResume void ()
OnPause void ()
OnStop void ()
OnDestroy void ()

Toutes ces méthodes sont des crochets que vous pouvez substituer à faire un travail approprié lorsque les changements d'état. Toutes les activités doivent mettre en œuvre onCreate () pour effectuer le réglage initial lorsque l'objet est d'abord instancié. Beaucoup mettra également en œuvre OnPause () pour valider les modifications de données et contraire se préparer à arrêter l'interaction avec l'utilisateur.

Pris ensemble, ces sept méthodes définir le cycle de vie complet d'une activité. Il ya trois boucles imbriquées que vous pouvez contrôler par leur mise en œuvre:

  • La vie entière d'une activité qui se passe entre le premier appel à onCreate () par le biais d'une finale seul appel à OnDestroy (). Une activité ne l'ensemble de ses configuration initiale de "global" dans l'état onCreate (), et libère toutes les ressources restantes OnDestroy (). Par exemple, si elle a un fil conducteur dans l'arrière-plan pour télécharger des données depuis le réseau, il peut créer ce thread dans onCreate () et puis arrêtez le fil en OnDestroy ().
  • La durée de vie visible d'une activité qui se passe entre un appel à onStart () jusqu'à ce qu'un appel correspondant à OnStop (). Pendant ce temps, l'utilisateur peut voir l'activité à l'écran, mais il peut ne pas être au premier plan et l'interaction avec l'utilisateur . Entre ces deux méthodes, vous pouvez maintenir les ressources qui sont nécessaires pour montrer l'activité de l'utilisateur. Par exemple, vous pouvez enregistrer un BroadcastReceiver dans onStart () de surveiller les modifications que l'impact de votre assurance-chômage, et annuler l'inscription dans OnStop () lorsque le utilisateur ne peut plus voir ce que vous affichez. Le onStart () et OnStop () méthodes peuvent être appelées à plusieurs reprises, que l'activité alterne entre être visibles et cachés à l'utilisateur.

  • La durée de vie de premier plan d'une activité qui se passe entre un appel à onResume () jusqu'à ce qu'un appel correspondant à OnPause (). Pendant ce temps, l'activité est en face de toutes les autres activités à l'écran et est en interaction avec l'utilisateur. Une activité peut souvent transition entre la reprise et s'arrêta Etats - par exemple, OnPause () est appelée lorsque le dispositif se met en veille ou quand une nouvelle activité est lancée, onResume () est appelée quand un résultat d'activité ou une intention neufs sont livrés. Par conséquent, le code de ces deux méthodes doivent être assez léger.

Le schéma suivant illustre ces boucles et les chemins d'une activité peut prendre entre les Etats. Les ovales de couleur sont les principaux États de l'activité peut être en rectangles Les carrés représentent les méthodes de rappel, vous pouvez mettre en œuvre pour effectuer des opérations lorsque les transitions entre les états d'activité.

State diagram for an Android activity lifecycle.

Le tableau suivant décrit chacune de ces méthodes plus en détail et il localise dans l'ensemble du cycle de vie l'activité de l':

Méthode Description Killable? Suivant
onCreate () Appelé lorsque l'activité est d'abord créé -. C'est là que vous devez faire tous vos statique normale créé créer des vues, lier des données à des listes, et ainsi de suite. Cette méthode est passé un paquet contenant l'objet de l'activité de l'état précédent, si cet état a été capturé (voir activité d'épargne d'État, plus tard).

Toujours suivie par onStart ().

N onStart ()
     onRestart () Appelé après l'activité a été arrêtée, juste avant qu'elle ne soit relancée.

Toujours suivie par onStart ()

N onStart ()
onStart () Appelé juste avant l'activité devient visible pour l'utilisateur.

Suivi par onResume () si l'activité est au premier plan, ou OnStop () si elle est masquée.

N onResume ()
ou
OnStop ()
     onResume () Appelée juste avant que l'activité commence à interagir avec l'utilisateur. À ce stade, l'activité est au sommet de la pile d'activité, avec l'entrée d'utilisateur y aller.

Toujours suivie par OnPause ().

N OnPause ()
OnPause () Appelé lorsque le système est sur le point de commencer à reprendre une autre activité. Cette méthode est généralement utilisée pour valider les modifications non enregistrées de données persistantes, arrêter des animations et des autres choses qui peuvent être CPU consomme, et ainsi de suite. Il convient de faire tout ce qu'il fait très rapidement, parce que la prochaine activité ne seront pas repris jusqu'à ce qu'il revienne.

Suivie, soit onResume () si l'activité revient à l'avant, ou par OnStop () si elle devient invisible pour l'utilisateur.

Oui onResume ()
ou
OnStop ()
OnStop () Appelé lorsque l'activité n'est plus visible pour l'utilisateur. Cela peut se produire car il est détruit, ou en raison d'une autre activité (que ce soit un existant ou un nouveau) a été repris et la couvrir.

Suivie, soit onRestart () si l'activité est de revenir à interagir avec l'utilisateur, ou par OnDestroy () si cette activité s'en va.

Oui onRestart ()
ou
OnDestroy ()
OnDestroy () Appelé avant que l'activité est détruit. C'est le dernier appel que l'activité va recevoir. Il pourrait être appelé soit parce que l'activité est de finition (quelqu'un a appelé finish () sur lui), ou parce que le système est temporairement détruire cette instance de l'activité pour économiser l'espace. Vous pouvez établir une distinction entre ces deux scénarios avec le isFinishing () méthode. Oui rien

Note de la killable colonne dans le tableau ci-dessus. Il indique si le système peut tuer le processus d'hébergement de l'activité à tout moment après le retour de la méthode, sans exécuter une autre ligne d'activité du code de l'. Trois méthodes (OnPause (), OnStop (), et OnDestroy ()) sont marqués "Oui." Parce que OnPause () est le premier des trois, c'est le seul qui est garanti pour être appelée avant que le processus est tué - OnStop () et OnDestroy () peut ne pas être. Par conséquent, vous devez utiliser OnPause () pour écrire les données persistantes (tels que l'utilisateur modifie) aux installations de stockage.

Les méthodes qui sont marqués «Non» dans le killable colonne de protéger le processus d'hébergement de l'activité d'être tué dès le moment où ils sont appelés. Ainsi, une activité est dans un état killable, par exemple, à partir du moment OnPause () retourne à l'époque onResume () est appelée. Il ne sera pas de nouveau jusqu'à ce que killable OnPause () retourne à nouveau.

Comme indiqué dans une section plus tard, les processus et du cycle de vie, une activité qui n'est pas techniquement "killable» par cette définition pourrait encore être tués par le système - mais que se passerait-il que dans des circonstances extrêmes et dire quand il n'y a pas d'autre recours.

Enregistrer l'état d'activité

Lorsque le système, plutôt que de l'utilisateur, arrête une activité pour économiser de la mémoire, l'utilisateur peut s'attendre à retourner à l'activité et trouve dans son état antérieur.

Pour capturer cet état avant que l'activité est tué, vous pouvez mettre en œuvre un onSaveInstanceState () méthode de l'activité. Android appelle cette méthode avant de faire l'activité susceptibles d'être détruits - qui est, avant OnPause () est appelée. Il passe à la méthode une Bundle objet où vous pouvez enregistrer l'état dynamique de l'activité, la valeur des paires nom. Lorsque l'activité est de nouveau relancée, le forfait est passé à la fois à onCreate () et à une méthode appelée après onStart (), onRestoreInstanceState (), de sorte que l'une ou les deux peuvent recréer l'état capturé.

Contrairement OnPause () et les autres méthodes discuté plus tôt, onSaveInstanceState () et onRestoreInstanceState () ne sont pas du cycle de vie des méthodes. Ils ne sont pas toujours appelé. Par exemple, Android appels onSaveInstanceState () avant que l'activité devient vulnérable à la destruction par le système, mais ne se soucie pas de l'appeler lorsque l'instance est en fait détruit par une action de l'utilisateur (par exemple en appuyant sur la touche BACK). Dans ce cas, l'utilisateur ne sera pas attendre pour revenir à l'activité, il n'y a donc aucune raison pour enregistrer son état.

Parce que onSaveInstanceState () n'est pas toujours appelée, vous devez l'utiliser seulement pour enregistrer l'état transitoire de l'activité, de ne pas stocker les données persistantes. Utilisez OnPause () à cet effet au lieu.

Coordonner les activités

Quand on commence une autre activité, ils ont tous deux transitions du cycle de vie d'expérience. Une pause et il peut arrêter, tandis que l'autre se met en place. À l'occasion, vous pourriez avoir besoin pour coordonner ces activités, l'une avec l'autre.

L'ordre des rappels de cycle de vie est bien défini, en particulier lorsque les deux activités sont dans le même processus:

  1. L'activité en cours OnPause () méthode est appelée.
  2. Ensuite, l'activité de départ de onCreate (), onStart (), et onResume () méthodes sont appelées dans l'ordre.
  3. Ensuite, si l'activité de départ n'est plus visible à l'écran, ses OnStop () méthode est appelée.

cycle de vie des services

Un service peut être utilisé de deux façons:

  • Il peut être lancé et autorisé à s'exécuter jusqu'à ce que quelqu'un s'arrête ou se bloque. Dans ce mode, il a commencé par appeler Context.startService () et s'est arrêté en appelant Context.stopService (). Il peut lui-même arrêter en appelant Service.stopSelf () ou Service.stopSelfResult (). Une seule stopService () d'appel est nécessaire pour arrêter le service, peu importe combien de fois startService () a été appelé.
  • It can be operated programmatically using an interface that it defines and exports. Clients establish a connection to the Service object and use that connection to call into the service. The connection is established by calling Context.bindService(), and is closed by calling Context.unbindService(). Multiple clients can bind to the same service. If the service has not already been launched, bindService() can optionally launch it.

The two modes are not entirely separate. You can bind to a service that was started with startService(). For example, a background music service could be started by calling startService() with an Intent object that identifies the music to play. Only later, possibly when the user wants to exercise some control over the player or get information about the current song, would an activity establish a connection to the service by calling bindService(). In cases like this, stopService() will not actually stop the service until the last binding is closed.

Like an activity, a service has lifecycle methods that you can implement to monitor changes in its state. But they are fewer than the activity methods — only three — and they are public, not protected:

void onCreate()
void onStart(Intent intent)
void onDestroy()

By implementing these methods, you can monitor two nested loops of the service's lifecycle:

  • The entire lifetime of a service happens between the time onCreate() is called and the time onDestroy() returns. Like an activity, a service does its initial setup in onCreate(), and releases all remaining resources in onDestroy(). For example, a music playback service could create the thread where the music will be played in onCreate(), and then stop the thread in onDestroy().
  • The active lifetime of a service begins with a call to onStart(). This method is handed the Intent object that was passed to startService(). The music service would open the Intent to discover which music to play, and begin the playback.

    There's no equivalent callback for when the service stops — no onStop() method.

The onCreate() and onDestroy() methods are called for all services, whether they're started by Context.startService() or Context.bindService(). However, onStart() is called only for services started by startService().

If a service permits others to bind to it, there are additional callback methods for it to implement:

IBinder onBind(Intent intent)
boolean onUnbind(Intent intent)
void onRebind(Intent intent)

The onBind() callback is passed the Intent object that was passed to bindService and onUnbind() is handed the intent that was passed to unbindService(). If the service permits the binding, onBind() returns the communications channel that clients use to interact with the service. The onUnbind() method can ask for onRebind() to be called if a new client connects to the service.

The following diagram illustrates the callback methods for a service. Although, it separates services that are created via startService from those created by bindService(), keep in mind that any service, no matter how it's started, can potentially allow clients to bind to it, so any service may receive onBind() and onUnbind() calls.

State diagram for Service callbacks.

Broadcast receiver lifecycle

A broadcast receiver has single callback method:

void onReceive(Context curContext, Intent broadcastMsg)

When a broadcast message arrives for the receiver, Android calls its onReceive() method and passes it the Intent object containing the message. The broadcast receiver is considered to be active only while it is executing this method. When onReceive() returns, it is inactive.

A process with an active broadcast receiver is protected from being killed. But a process with only inactive components can be killed by the system at any time, when the memory it consumes is needed by other processes.

This presents a problem when the response to a broadcast message is time consuming and, therefore, something that should be done in a separate thread, away from the main thread where other components of the user interface run. If onReceive() spawns the thread and then returns, the entire process, including the new thread, is judged to be inactive (unless other application components are active in the process), putting it in jeopardy of being killed. The solution to this problem is for onReceive() to start a service and let the service do the job, so the system knows that there is still active work being done in the process.

The next section has more on the vulnerability of processes to being killed.

Processes and lifecycles

The Android system tries to maintain an application process for as long as possible, but eventually it will need to remove old processes when memory runs low. To determine which processes to keep and which to kill, Android places each process into an "importance hierarchy" based on the components running in it and the state of those components. Processes with the lowest importance are eliminated first, then those with the next lowest, and so on. There are five levels in the hierarchy. The following list presents them in order of importance:

  1. A foreground process is one that is required for what the user is currently doing. A process is considered to be in the foreground if any of the following conditions hold:
    • It is running an activity that the user is interacting with (the Activity object's onResume() method has been called).
    • It hosts a service that's bound to the activity that the user is interacting with.

    • It has a Service object that's executing one of its lifecycle callbacks (onCreate(), onStart(), or onDestroy()).

    • It has a BroadcastReceiver object that's executing its onReceive() method.

    Only a few foreground processes will exist at any given time. They are killed only as a last resort — if memory is so low that they cannot all continue to run. Generally, at that point, the device has reached a memory paging state, so killing some foreground processes is required to keep the user interface responsive.

  2. A visible process is one that doesn't have any foreground components, but still can affect what the user sees on screen. A process is considered to be visible if either of the following conditions holds:

    • It hosts an activity that is not in the foreground, but is still visible to the user (its onPause() method has been called). This may occur, for example, if the foreground activity is a dialog that allows the previous activity to be seen behind it.
    • It hosts a service that's bound to a visible activity.

    A visible process is considered extremely important and will not be killed unless doing so is required to keep all foreground processes running.

  3. A service process is one that is running a service that has been started with the startService() method and that does not fall into either of the two higher categories. Although service processes are not directly tied to anything the user sees, they are generally doing things that the user cares about (such as playing an mp3 in the background or downloading data on the network), so the system keeps them running unless there's not enough memory to retain them along with all foreground and visible processes.

  4. A background process is one holding an activity that's not currently visible to the user (the Activity object's onStop() method has been called). These processes have no direct impact on the user experience, and can be killed at any time to reclaim memory for a foreground, visible, or service process. Usually there are many background processes running, so they are kept in an LRU (least recently used) list to ensure that the process with the activity that was most recently seen by the user is the last to be killed. If an activity implements its lifecycle methods correctly, and captures its current state, killing its process will not have a deleterious effect on the user experience.

  5. An empty process is one that doesn't hold any active application components. The only reason to keep such a process around is as a cache to improve startup time the next time a component needs to run in it. The system often kills these processes in order to balance overall system resources between process caches and the underlying kernel caches.

Android ranks a process at the highest level it can, based upon the importance of the components currently active in the process. For example, if a process hosts a service and a visible activity, the process will be ranked as a visible process, not a service process.

In addition, a process's ranking may be increased because other processes are dependent on it. A process that is serving another process can never be ranked lower than the process it is serving. For example, if a content provider in process A is serving a client in process B, or if a service in process A is bound to a component in process B, process A will always be considered at least as important as process B.

Because a process running a service is ranked higher than one with background activities, an activity that initiates a long-running operation might do well to start a service for that operation, rather than simply spawn a thread — particularly if the operation will likely outlast the activity. Examples of this are playing music in the background and uploading a picture taken by the camera to a web site. Using a service guarantees that the operation will have at least "service process" priority, regardless of what happens to the activity. As noted in the Broadcast receiver lifecycle section earlier, this is the same reason that broadcast receivers should employ services rather than simply put time-consuming operations in a thread.

↑ Go to top