Android tuera un processus s'il est en arrière-plan et le système d'exploitation décide qu'il a besoin des ressources (RAM, CPU, etc.). Je dois être capable de simuler ce comportement pendant les tests afin de pouvoir m'assurer que mon application se comporte correctement. Je veux pouvoir le faire de manière automatisée afin de pouvoir tester si l'application se comporte correctement chaque fois que cela se produit, ce qui signifie que je devrai tester cela dans chaque activité, etc.
Je sais comment tuer mon processus. Ce n'est pas le problème. Le problème est que lorsque je tue mon processus ( en utilisant DDMS, adb shell kill
, Process.killProcess()
, etc.) Android ne redémarre pas de la même façon qu'il serait si le système d' exploitation Android avait tué lui - même.
Si le système d'exploitation Android tue le processus (en raison des besoins en ressources), lorsque l'utilisateur revient à l'application, Android recrée le processus, puis recrée l' activité principale sur la pile d'activités (appel onCreate()
).
D'un autre côté, si je tue le processus, Android suppose que l'activité en haut de la pile d'activités s'est mal comportée , donc il recrée automatiquement le processus, puis supprime l'activité supérieure de la pile d'activités et recrée l'activité qui se trouvait en dessous l'activité principale (appelant onCreate () `). Ce n'est pas le comportement que je souhaite. Je veux le même comportement que lorsque Android tue le processus.
Juste pour expliquer en images, si ma pile d'activités ressemble à ceci:
ActivityA -> ActivityB -> ActivityC -> ActivityD
Si Android arrête le processus et que l'utilisateur retourne à l'application, Android recrée le processus et crée ActivityD.
Si je tue le processus, Android recrée le processus et crée ActivityC.
Réponses:
La meilleure façon de tester cela pour moi était de faire ceci:
Terminate Application
dans la fenêtre Logcat dans Android Studio (cela tuera le processus de l'application, assurez-vous de sélectionner votre appareil et de traiter dans les listes déroulantes Logcat en haut)Sur certains appareils, vous pouvez également revenir à l'application (ActivityD) avec Applications -> Icône de votre lanceur, mais sur d'autres appareils, il démarrera à la place ActivityA.
Voici ce que disent les documents Android à ce sujet:
la source
<activity>
balise dans le manifeste.Cela semble fonctionner pour moi:
Ceci est différent de celui
adb shell kill
mentionné par l'OP.Notez que l'aide de la
am kill
commande dit:Donc, cela ne tuera pas le processus s'il est au premier plan. Cela semble fonctionner comme l'OP le souhaitait en ce sens que si je quitte mon application, l'exécuter
adb shell am kill <package_name>
tuera l'application (je l'ai confirmé en utilisantps
sur l'appareil). Ensuite, si je retourne à l'application, je suis de retour dans l'activité dans laquelle j'étais auparavant - c'est-à-dire dans l'exemple de l'OP, le processus est recréé et crée ActivityD (plutôt qu'ActivityC comme la plupart des autres méthodes de mise à mort semblent se déclencher).Désolé, j'ai quelques années de retard pour l'OP, mais j'espère que d'autres trouveront cela utile.
la source
adb shell am force-stop
. Le dernier supprimera également tous les pendingIntent liés à votre application (comme les notifications), contrairement au premier.am kill
.ps
montre mon applicationUne autre méthode, probablement scriptable car elle ne nécessite pas de DDMS:
Configuration unique: accédez aux Options du développeur, sélectionnez Paramètre de limite de processus d'arrière-plan, modifiez la valeur de «Limite standard» à «Aucun processus d'arrière-plan».
Lorsque vous devez redémarrer le processus, appuyez sur le bouton d'accueil. Le processus sera tué (vous pouvez vérifier dans logcat / Android Monitor en studio - le processus sera marqué [DEAD]). Revenez ensuite à l'application à l'aide du sélecteur de tâches.
la source
Cette question est ancienne mais, il existe une réponse à cette question qui ne nécessite pas adb, Android Studio, etc. La seule exigence est l'API 23 ou plus récente.
Pour simuler le redémarrage de l'application par système d'exploitation, accédez aux paramètres de l'application pendant que votre application est en cours d'exécution, désactivez (vous pouvez ensuite activer) une autorisation et renvoyez l'application à partir des applications récentes. Lorsque l'autorisation est désactivée, le système d'exploitation tue l'application mais conserve les états d'instance enregistrés. Lorsque l'utilisateur renvoie l'application, l'application et la dernière activité (avec l'état enregistré) sont recréées.
La méthode «Aucun processus d'arrière-plan» provoque parfois le même comportement, mais pas toujours. Par exemple, si l'application exécute un service d'arrière-plan, "Aucun processus d'arrière-plan" ne fait rien. Mais l'application peut être tuée par le système, y compris ses services. La méthode d'autorisation fonctionne même si l'application dispose d'un service.
Exemple:
Notre application a deux activités. ActivityA est l'activité principale qui est lancée à partir du lanceur. ActivityB est démarré à partir de ActivityA. Je montrerai seulement les méthodes onCreate, onStart, onStop, onDestroy. Android appelle onSaveInstanceState toujours avant d'appeler onStop, car une activité qui est à l'état d'arrêt peut être tuée par le système. [ https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle]
Méthode d'autorisation:
Je veux comparer d'autres méthodes qui sont mentionnées sur les autres réponses.
Ne pas conserver les activités: cela ne tue pas l'application.
Méthode d'arrêt forcé: ne stocke pas les états d'instance enregistrés
la source
Service
tué de nombreuses fois. Même si le système ne manque pas de mémoire. La plupart des fabricants d'appareils ont écrit leurs propres «optimisations» et «améliorations» du système d'exploitation Android afin d'économiser l'énergie de la batterie. De nombreux appareils ont des «tueurs» beaucoup plus agressifs qu'Android standard.Je suis très en retard à la fête et plusieurs avant moi ont donné la même réponse correcte mais pour simplifier pour celui qui vient après moi, appuyez simplement sur le bouton d'accueil et exécutez cette commande:
adb shell ps | grep <package name> | awk '{print $2}' | xargs adb shell run-as <package name again> kill
L'application ne perdra pas son état et, d'après ma propre expérience, cela fonctionne de la même manière que le système d'exploitation a tué l'application en arrière-plan. Cela ne fonctionne que pour les applications créées par débogage
la source
'grep' is not recognized as an internal or external command, operable program or batch file.
run-as <package name> kill 7379
, mais cela m'a mis à l'activité précédente, pas à l'activité à laquelle j'étais lorsque j'ai appuyé sur le bouton d'accueil.Voici comment procéder dans Android Studio.
la source
Android Monitor - Monitors
. Ça doit être quelque chose dont ils se sont débarrassés. Je suis sur la version 3.2.1Mettez l'application en arrière-plan avec le bouton HOME
Sélectionnez votre processus en mode "Logcat" dans Android Studio, puis cliquez sur Terminer l'application dans le coin inférieur gauche
Maintenant, lancez votre application à partir du lanceur sur un appareil Android
EDIT: Selon Internet, ce qui suit fonctionne également:
EDIT from the future: quelque chose à noter, il y a eu un changement dans Android Studio 4.0, si vous utilisez à
Run
partir d'AS, alorsTerminate
émettra un fichierForce Stop
.Cependant, si vous lancez à partir du lanceur par la suite, et ALORS vous essayez de le simuler de cette façon, vous obtiendrez les résultats que vous souhaitez (comportement de mémoire faible).
la source
the behaviour is not the same as what happens when Android kills the process
oui c'estVous pouvez effectuer les étapes suivantes pour reproduire le comportement recherché:
la source
Dans les options du développeur sous Paramètres, sélectionnez «Ne pas conserver les activités», ce qui détruira les activités dès que vous vous en éloignerez.
Remarque: conformément à un commentaire utile ci-dessous, ne l'utilisez que si vous ne vous souciez pas de l'effacement des valeurs statiques.
la source
Appuyez sur le bouton Accueil et placez d'abord l'application en arrière-plan. Arrêtez ou arrêtez ensuite le processus à partir de DDMS ou ADB.
la source
Vous pouvez également vous connecter à votre appareil / émulateur à partir du terminal avec
adb shell
, puis obtenir le PID de votre processus avecps | grep <your_package_name
et l'exécuterkill -9 <pid>
. Ensuite, ouvrez votre application réduite à partir du sélecteur d'applications récentes et elle redémarrera la dernière activitéla source
La racine de votre problème semble être que vous
Activity
êtes au premier plan lorsque vous tuez le processus.Vous pouvez observer cela en appuyant sur stop dans DDMS quand
Activity
est visible (se produit exactement ce que vous décrivez) et en comparant cela à appuyer sur stop après la maison et à revenir plus tard à l'application.Assurez-vous simplement de le faire
moveTaskToBack(true)
dans vos tests.la source
Je ne suis pas sûr que ce soit la réponse que vous recherchez, c'est plutôt une réflexion logique.
Je ne pense pas que vous puissiez vraiment faire un test entièrement automatisé, le seul moyen de le simuler, ce sera de le recréer, AKA a tellement d'activités qu'Android va tuer votre application.
Donc, mon idée ou suggestion est de créer une autre petite application, qui continue de faire apparaître de nouvelles activités, jusqu'à ce qu'Android manque de mémoire et commence à tuer le processus en arrière-plan.
Quelque chose parmi la ligne:
Démarrer l'activité i -> Vérifier le processus en cours si l'application est dans la liste, incrémenter i et redémarrer la boucle sans fermer l'activité actuelle, sinon -> diminuer i et fermer l'activité actuelle, revenir à la précédente et revérifier ...
la source
Lorsque le processus de candidature meurt, Android parcourt les enregistrements d'activités (les entrées représentent des activités dans la pile d'historique) et décide lesquelles conserver dans l'historique et celles à supprimer.
L'un des points clés ici est le
ActivityRecord
champ appeléhaveState
, que les ingénieurs d'Android Framework décrivent comme "avons-nous obtenu le dernier état d'activité?".Par défaut, Android considère que l'activité a un état. L'activité devient sans état lorsque l'application signale au service du gestionnaire de tâches d'activité que l'activité a repris et cela est valide jusqu'à ce que l'application notifie à l' infrastructure que l'activité est entrée dans l'état Arrêté. En termes simples, la
haveState
valeur estfalse
entre l'activitéonResume()
est appelée etonStop()
ouonSaveInstanceState()
est appelée, selon la version cible de l'application.Dans ce cas, ActivityD n'a pas d'
android:stateNotNeeded="true"
attribut dans le manifeste de l'application et il est actuellement en cours d'exécution au premier plan, donc Android le supprime de l'historique car le système n'a pas obtenu son dernier état.Comme cela a été mentionné à plusieurs reprises, vous pouvez simplement déplacer l'application en arrière-plan, de sorte que l'activité principale de la pile arrière d'activité enregistre son état, et après cela, vous pouvez tuer le processus d'application via Android Debug Bridge, Android Studio ou en utilisant le Propriété Limite des processus d'arrière-plan dans les options du développeur. Après cela, votre activité récente sera recréée avec succès.
Malgré cela, il existe également un autre moyen simple de tester le scénario de décès du processus de candidature. Sachant tout ce qui est décrit ci-dessus et le fait que si vous démarrez un nouvel ActivityE à partir de ActivityD en cours d'exécution, le
onStop()
rappel ActivityD n'est appelé qu'après laonResume()
méthode ActivityE , vous pouvez effectuer l'astuce suivante.Ensuite, commencez simplement
TerminatorActivity
lorsque vous souhaitez supprimer l'application.À la fin, il existe un outil léger qui simplifie les tests de la mort de votre processus d'application, appelé Venom .
la source