Libérer des ressources dans onPause au lieu de onDestroy

Il s'agit de POST-honeycomb (c. -à- d., Android 3.0+) et les citations ci-dessous viennent de https://developer.android.com/reference/android/app/Activity.html

Selon le cycle de vie, onStop et onDestroy sont éliminables, cela signifie:

  • Comment mettre à niveau un site Web pour les appareils mobiles?
  • Est-il correct d'appeler sendBroadcast () à partir d'un autre thread?
  • Où installer Android SDK sur Mac OS X?
  • Encodez / décodez AndroidManifest.xml dans APK
  • Comment faire une vue d'ensemble à l'écran
  • Changer MenuItem la couleur du texte par programme
  • Notez la colonne "Éliminer" dans le tableau ci-dessus – pour les méthodes qui sont marquées comme étant invalidables, après que la méthode renvoie l'hébergement du processus, l'activité peut être abattu par le système à tout moment sans qu'une autre ligne de son code soit exécuté

    1. En d'autres termes, onStop (le long des autres qui se produisent avant cet événement) est garanti pour être appelé, pourtant, au moment où la méthode revient, le processus pourrait mourir, donc onDestroy n'est pas appelé à être appelé.

      Une autre citation indique:

      Pour les méthodes qui ne sont pas marquées comme étant invalidantes, le processus de l'activité ne sera pas tué par le système à compter du moment où la méthode est appelée et se poursuivra après son retour.

      Suivi par

      Ainsi, une activité est dans l'état de destruction , par exemple, entre après onPause () au début de onResume ().

    2. Mais cela ne correspond pas à ce qui a été dit ci-dessus, sauf si cela ne correspond qu'à PRE-honeycomb . Ce n'est pas vrai pour POST-honeycomb , n'est-ce pas? Donc, essentiellement, onPause et onStop sont garantis.

    3. En supposant que je lance seulement une ressource sur Destroy, cela pourrait entraîner une fuite possible car onDestroy pourrait ne pas être appelé, n'est-ce pas?

    4. Cependant, est-ce que ce scénario (c'est-à-dire que onDestroy n'est pas appelé) se produit en plus du processus qui est tué par Android? Y a-t-il d'autres scénarios qui provoquent l'absence d'appel de DDR, et donc de la fuite de la ressource .

    5. Est-il vrai que lorsque Android tue le processus que les ressources seront détruites et qu'aucune fuite ne se produira (même si nous n'avons pas divulgué explicitement la ressource?).

    Veuillez fournir des informations détaillées pour savoir si ces énoncés (1) (2) (3) (4) (5) sont corrects ou non.

  • Pourquoi Android ne reçoit-il pas le certificat ssl incorrect? (Deux domaines, un serveur)
  • Suppression Android d'un fichier à partir d'un stockage interne
  • Android MapView chevauche DrawerLayout
  • Puis-je changer l'intensité de LED d'un appareil Android?
  • Comment puis-je détecter un clic dans un auditeur OnTouch?
  • Modifiez dynamiquement la disposition des lignes d'une ListView
  • 2 Solutions collect form web for “Libérer des ressources dans onPause au lieu de onDestroy”

    Tout d'abord, entendons ce qui se passe avec la documentation que vous avez citée.

    Les commandes suivantes montrent que git blame sortie du fichier Activity.java dans AOSP:

     $ cd $AOSP/frameworks/base $ git blame ./core/java/android/app/Activity.java 

    La partie pertinente de la sortie:

     9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 363) * <p>Note the "Killable" column in the above table -- for those methods that 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 364) * are marked as being killable, after that method returns the process hosting the 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 365) * activity may killed by the system <em>at any time</em> without another line 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 366) * of its code being executed. Because of this, you should use the 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 367) * {@link #onPause} method to write any persistent data (such as user edits) 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 368) * to storage. In addition, the method 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 369) * {@link #onSaveInstanceState(Bundle)} is called before placing the activity 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 370) * in such a background state, allowing you to save away any dynamic instance 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 371) * state in your activity into the given Bundle, to be later received in 550116576 (RoboErik 2014-07-09 15:05:53 -0700 372) * {@link #onCreate} if the activity needs to be re-created. 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 373) * See the <a href="#ProcessLifecycle">Process Lifecycle</a> 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 374) * section for more information on how the lifecycle of a process is tied 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 375) * to the activities it is hosting. Note that it is important to save 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 376) * persistent data in {@link #onPause} instead of {@link #onSaveInstanceState} 5c40f3fcc (Daisuke Miyakawa 2011-02-15 13:24:36 -0800 377) * because the latter is not part of the lifecycle callbacks, so will not 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 378) * be called in every situation as described in its documentation.</p> 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 379) * 0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 380) * <p class="note">Be aware that these semantics will change slightly between 0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 381) * applications targeting platforms starting with {@link android.os.Build.VERSION_CODES#HONEYCOMB} 0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 382) * vs. those targeting prior platforms. Starting with Honeycomb, an application 0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 383) * is not in the killable state until its {@link #onStop} has returned. This 0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 384) * impacts when {@link #onSaveInstanceState(Bundle)} may be called (it may be 0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 385) * safely called after {@link #onPause()} and allows and application to safely 0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 386) * wait until {@link #onStop()} to save persistent state.</p> 0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 387) * 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 388) * <p>For those methods that are not marked as being killable, the activity's 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 389) * process will not be killed by the system starting from the time the method 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 390) * is called and continuing after it returns. Thus an activity is in the killable 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 391) * state, for example, between after <code>onPause()</code> to the start of 9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 392) * <code>onResume()</code>.</p> 

    Notez que le paragraphe qui traite du comportement post-Honeycomb a été ajouté par Dianne Hackborn le 2010-12-07, alors que les paragraphes ci-joints datent de 2009-03-03.

    Ce qu'il nous dit, c'est que Dianne a ajouté le nouveau paragraphe sans mettre à jour le reste du javadoc, donc la contradiction. Malheureusement, ce n'est pas rare dans Android.

    A vos questions:

    1) Sur les versions post-Honeycomb d'Android, onResume() et onStop() sont appelés à être appelés (comme l'a déclaré Dianne Hackborn dans son ajout au javadoc d'activité).

    2) Sur pré-Honeycomb seulement onPause() est appelé à être appelé (comme l'indique la version antérieure du javadoc de l'activité)

    3,4,5) onDestroy() ne sera appelé que si le processus d'hébergement de l'application entière est tué. Lorsque le processus est tué, toutes les ressources qui lui sont allouées sont libérées, il n'y a donc aucun risque de fuite de mémoire dans ce cas.

    Note importante : puisque la libération de ressources dans onDestroy() ne provoquera pas de fuite de mémoire, il pourrait sembler être une bonne idée de mettre tout le code de "libération" là-bas. Cependant, c'est rarement l'approche optimale. Pourquoi? Lire ci-dessous.

    Lorsque l' Activity passe à l'arrière-plan, elle est arrêtée, mais pas détruite (habituellement). Activity peut rester dans cet état «arrêté» pendant une longue période et sera redémarré si l'utilisateur retourne à l'application. Si vous libérez des ressources dans onDestroy() , ce qui n'est pas appelé par défaut lorsque l' Activity va à l'arrière-plan, l' Activity se maintiendra sur ces ressources en état d'arrêt, ce qui entraînera une augmentation de la quantité de ressources à consommer par votre application en arrière-plan.

    Lorsque Android manque de mémoire, il commence à tuer les processus afin de libérer la mémoire consommée par eux. L'une des considérations les plus importantes prises en compte lors du choix des processus à tuer est leur consommation de ressources. Ainsi, si votre application détient les ressources en état d'arrêt, cela aura plus de chances d'être tué par Android.

    En outre, nous, les développeurs, devons nous assurer que nous créons les meilleures applications pour nos utilisateurs. L'application qui consomme une quantité non minimale de ressources et de batterie du téléphone utilisateur en arrière-plan n'est pas une bonne application. Et les utilisateurs le sauront!

    Par conséquent, je conseille fortement de publier toutes les ressources dans la méthode onStop() . Je ne onDestroy() généralement pas les méthodes onDestroy() dans Activities and Fragments .

    Corollaire: Comme l'a souligné @Juan dans son commentaire, la note importante ci-dessus a un corollaire tout aussi important, mais pas si évident: onStart() devrait être la seule méthode dans laquelle les ressources sont allouées. Quelle que soit votre définition de «ressources», ni onCreate() ni onResume() devraient affecter ces ressources.

    Je pense que Vasily a fourni une excellente réponse. Toujours, il y a un point petit mais important qui manque à ce sujet lié à

    1. Est-il vrai que lorsque Android tue le processus que les ressources seront détruites et qu'aucune fuite ne se produira (même si nous n'avons pas divulgué explicitement la ressource?).

    La réponse dépend de ce que vous craignez exactement. Comme Vasily l'a souligné, Android (basé sur Linux) est un système d'exploitation sécurisé moderne qui garantit que lorsque le processus est tué, toute la mémoire sera libérée, de plus tous les fichiers ouverts, les connexions réseau, etc. seront également correctement fermés. Donc, il n'y aura pas de fuite de ressources dans le sens habituel.

    Pourtant, il existe un scénario potentiellement problématique. Supposons que vous disposez d'une logique que vous effectuez lorsque vous publiez certaines ressources, c'est-à-dire quelque chose que vous mettez dans un destructeur en C ++ ou dans une implémentation de Closeable.close en Java. Par exemple, vous avez un cache en mémoire qui retarde les écritures dans un fichier avec le traitement par lots. Normalement, vous onDestroy ce cache en mémoire dans onDestroy et tout fonctionne bien. Mais lorsque le processus est onDestroy force par Android, onDestroy pourrait ne pas être appelé et votre logique de rinçage n'est pas exécutée et vous risquez donc de perdre des données et / ou d'avoir un état invalide dans votre stockage persistant. Donc, si vous avez quelque chose comme ça, vous devez assurer la cohérence en effectuant une telle logique dans un endroit plus fiable: onPause ou onStop .

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.