L'application Android sur laquelle je travaille remplace la classe Application pour stocker l'état léger (nom d'utilisateur, emplacement gps, etc.) dans les variables statiques. La plupart de cet état est défini dans OnCreate de l'activité de lancement (nom d'utilisateur extrait de prefs, le programme d'écoute d'emplacement s'exécute.) Est-il sûr de s'appuyer sur l'activité de lancement pour initialiser la classe Application? Y a-t-il des cas où la classe Application pourrait être recréée sans que l'activité de lancement ne soit également créée?
La question se pose car j'ai rencontré une exception de pointeur nul accédant à une variable de la classe Application lors de la reprise de l'application après que le téléphone ait dormi pendant plusieurs heures (l'application a été laissée au premier plan avant que le téléphone ne se mette en veille). Est-il possible que le processus ait été tué pendant que le téléphone était endormi et au réveil du téléphone, la classe Application a été recréée, l'activité supérieure de la pile a été reprise, mais l'activité de lancement.onCreate n'a pas été exécutée ainsi la classe Application n'a pas été initialisé?
Notez que j'ai essayé de tester ces types de scénarios en forçant l'application à cesser d'utiliser les applications Paramètres/Gérer. Cependant, je ne suis pas en mesure de recréer le problème. Lors de la prochaine exécution, la classe Application est créée, suivie du lancement activity.onCreate.
Est-il sûr de supposer que l'instance de classe Application existera aussi longtemps que le processus, et que lorsque la classe Application est créée, elle équivaut à "redémarrer" l'application, c'est-à-dire commencer par une nouvelle pile d'activités (et d'abord l'activité sur la pile est l'activité de lancement)?
Non. Votre application entière peut être supprimée et recréée avec la pile de tâches intacte; cela permet au système de récupérer de la mémoire sur les appareils qui en ont besoin tout en présentant une illusion transparente de multitâche à l'utilisateur final. De la documentation:
Une activité en arrière-plan (une activité qui n'est pas visible pour l'utilisateur et qui a été interrompue) n'est plus critique, de sorte que le système peut arrêter son processus en toute sécurité pour récupérer de la mémoire pour d'autres processus de premier plan ou visibles. Si son processus doit être arrêté, lorsque l'utilisateur revient à l'activité (la rendant à nouveau visible à l'écran), sa méthode onCreate (Bundle) sera appelée avec leStartInstanceState qu'il avait précédemment fourni dans onSaveInstanceState (Bundle) afin qu'elle peut se redémarrer dans le même état que le dernier utilisateur l'a quitté.
Autrement dit, le processus (auquel l'Application est liée) peut être interrompu mais redémarré, et les activités individuelles devraient avoir suffisamment d'informations pour se recréer à partir de ce qu'elles ont enregistré avant d'être tué, sans se fier à l'état global défini dans le processus par d'autres activités.
Envisagez de stocker un état partagé persistant qui doit être initialisé par une activité dans une base de données SharedPreference ou SQLite, ou de le transmettre aux activités qui en ont besoin en tant qu'intention supplémentaire.
Vous pouvez tester le scénario avec killing the process
De votre application en cours d'exécution.
Étape 1. Ouvrez votre application, puis appuyez sur le bouton Home
pour la masquer en arrière-plan.
Étape 2. Appelez adb Shell
Étape 3. Entrez la commande su
(vous devez obtenir l'autorisation ROOT pour tuer le processus)
Étape 4. ps
(répertoriez tous les ID de processus en cours d'exécution et trouvez le vôtre)
Étape 5. kill 1234
(Supposez que votre application s'exécute sur le processus 1234)
Étape 6. Ensuite, revenez à votre appareil et cliquez à nouveau sur l'icône de lancement. Vous pouvez trouver que la dernière activité de la pile d'activités est rouverte. Vous pouvez également trouver que la méthode onRestoreInstanceState()
est appelée pour l'activité.
En bref: faire l'initiation dans YourApplication.onCreate
, pas une LaunchActivity
Documents à vérifier:
- Processus et Threads
- Guides API> Activités
Est-il sûr de s'appuyer sur l'activité de lancement pour initialiser la classe Application?
Oui, tant que vous vous souvenez que l'application peut exister plus longtemps que cette activité et que l'activité peut être supprimée et recréée. Je ne sais pas quelle intention ressuscitera l'activité: LANCEMENT ou VUE (pour le scénario où l'activité a été tuée comme trop lourde, alors qu'il y avait un service de longue durée lié à l'application)
Existe-t-il des cas où la classe Application pourrait être recréée sans que l'activité de lancement ne soit également créée?
oui, si la dernière activité visible n'était pas LaunchActivity
check cycle de vie de l'application Android et utilisation de l'électricité statique
Est-il possible que le processus ait été tué pendant que le téléphone était endormi et au réveil du téléphone, la classe Application a été recréée, l'activité supérieure de la pile a été reprise, mais l'activité de lancement.onCreate n'a pas été exécutée ainsi la classe Application n'a pas été initialisé?
S'il y avait plusieurs activités différentes lancées A, B, C et leur processus entier tué, alors je pense que Android OS est bon avec seulement la création d'activités Application et C, tandis que A et B seraient à nouveau se sont crées à l'accès, c'est-à-dire en y retournant.
Est-il sûr de supposer que l'instance de classe Application existera aussi longtemps que le processus,
oui
et que lorsque la classe Application est créée, elle équivaut à "redémarrer" l'application, c'est-à-dire. commencer par une nouvelle pile d'activités (et la première activité sur la pile est l'activité de lancement)?
Je ne sais pas quand le redémarrage de l'activité de lancement sera appelé en premier,
mais le dernier, c'est-à-dire celui que l'utilisateur devrait voir.
"J'ai rencontré une exception de pointeur nul accédant à une variable de la classe Application lors de la reprise de l'application"
Vérifiez ce lien .. http://www.developerphil.com/dont-store-data-in-the-application-object/