Comment simuler Android en tuant mon processus

174

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.

David Wasser
la source
4
Ne pourriez-vous pas simplement créer la quantité de processus nécessaires pour tuer le vôtre en arrière-plan?
Alex W
2
@Pang Je pense que vous manquez le point. Je sais comment détecter qu'Android a tué le processus. J'ai du code qui gère ces conditions. Ce que je veux faire, c'est tester correctement (et de manière automatisée) ce code . Pour ce faire, j'ai besoin d'un moyen de provoquer Android pour qu'il tue mon processus exactement de la même manière qu'il le ferait normalement sous la pression des ressources. La question liée, bien qu'intéressante, n'ajoute aucune valeur ici.
David Wasser
@IgorGanapolsky Merci pour les liens, mais en fait aucun de ces liens n'a de solution au problème.
David Wasser

Réponses:

127

La meilleure façon de tester cela pour moi était de faire ceci:

  • Ouvrez ActivityD dans votre application
  • Appuyez sur le bouton Accueil
  • Appuyez sur Terminate Applicationdans 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)
  • Revenez à l'application avec un appui long sur Accueil ou des applications ouvertes (dépend de l'appareil)
  • L'application démarrera dans ActivityD recréé (ActivityA, ActivityB, ActivityC sont morts et seront recréés lorsque vous y reviendrez)

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:

Normalement, le système efface une tâche (supprime toutes les activités de la pile au-dessus de l'activité racine) dans certaines situations lorsque l'utilisateur sélectionne à nouveau cette tâche à partir de l'écran d'accueil. En règle générale, cela est fait si l'utilisateur n'a pas visité la tâche pendant un certain temps, par exemple 30 minutes.

marque
la source
2
Merci pour votre réponse mais cela ne m'est pas utile car j'ai besoin d'un moyen automatisé pour le faire, pour des tests automatisés.
David Wasser
1
Cela m'a vraiment aidé.
John Roberts
6
Ce n'est pas automatisé mais cela a parfaitement fonctionné pour mes besoins. Il est très important de ne pas sauter l' étape 2 . Vous devez envoyer l'application en arrière-plan avant d'arrêter le processus dans DDMS pour que cela fonctionne. Pour ceux qui se demandent d'où viennent les citations de doc, c'est ici . Bien que je ne sois pas sûr qu'ils soient réellement liés au sujet, car il s'agit de la <activity>balise dans le manifeste.
Tony Chan
1
Exactement ce dont j'avais besoin. Je vous remercie. Pour ceux qui ne le savent pas, DDMS est dans Eclipse, allez dans Fenêtre -> Ouvrir la perspective, et vous devriez le trouver là.
Richard
4
Sinon, vous pouvez aller dans "Options de développement" et définir la limite d'arrière-plan sur "aucun processus d'arrière-plan", puis chaque fois que vous appuyez sur home, le processus mourra.
Joao Gavazzi
56

Cela semble fonctionner pour moi:

adb shell am kill <package_name>

Ceci est différent de celui adb shell killmentionné par l'OP.

Notez que l'aide de la am killcommande dit:

am kill: Kill all processes associated with <PACKAGE>.  Only kills.
  processes that are safe to kill -- that is, will not impact the user
  experience.

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 utilisant pssur 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.

HexAndBugs
la source
Merci! C'est ce que je cherchais! Je souhaite préciser que cette commande se comporte différemment de adb shell am force-stop. Le dernier supprimera également tous les pendingIntent liés à votre application (comme les notifications), contrairement au premier.
bonnyz
Désigne quiconque étudie le code source du système d'exploitation pour voir quel code il exécute lorsqu'il tue un processus de récupération de mémoire - mon pari est que c'est le même code que am kill.
androidguy
ne fonctionne pas sur Android 7.1 Samsung J5. psmontre mon application
Valgaal
17

Une 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.

Merk
la source
2
Intéressant. Je pense que cela n'affecte pas les services Foreground, non?
IgorGanapolsky
Je dois le faire sur des appareils réels exécutant Android aussi vieux que 2.3.3, donc cela n'aide pas.
David Wasser
13

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:

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop (the order is like this, it is stopped after new one is started)
<go settings>
ActivityB onStop
<disable a permission>
//Application is killed, but onDestroy methods are not called.
//Android does not call onDestroy methods if app will be killed.
<return app by recent apps>
Application onCreate (this is the important part. All static variables are reset.)
ActivityB onCreate WITH savedInstance (user does not notice activity is recreated)
//Note that ActivityA is not created yet, do not try to access it.
ActivityB onStart
<return ActivityA by back>
ActivityA onCreate WITH savedInstance (user does not notice activity is recreated)
ActivityA onStart
ActivityB onStop
ActivityB onDestroy
<press back again, return launcher>
ActivityA onStop
ActivityA onDestroy
<open app again>
//does not call Application onCreate, app was not killed
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart

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.

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop
ActivityA onDestroy (do not keep)
<return launcher by home button>
ActivityB onStop
ActivityB onDestroy (do not keep) 
<retun app from recent apps>
// NO Application onCreate
ActivityB onCreate WITH savedInstance (user does not notice activity recreated)
ActivityB onStart
<return ActivityA by back>
ActivityA onCreate WITH savedInstance (user does not notice activity recreated)
ActivityA onStart
ActivityB onStop
ActivityB onDestroy
<press back again, return launcher>
ActivityA onStop
ActivityA onDestroy
<open app again>
//does not call Application onCreate, app was not killed
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart

Méthode d'arrêt forcé: ne stocke pas les états d'instance enregistrés

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop
<go settings>
ActivityB onStop
<force stop, return app from recent apps>
Application onCreate
ActivityA onCreate WITHOUT savedInstance 
//This is important part, app is destroyed by user.
//Root activity of the task is started, not the top activity.
//Also there is no savedInstance.
fthdgn
la source
~ "l' application peut être tuée par le système, y compris son service ". Not Foreground Service ...
IgorGanapolsky
@DavidWasser Lisez les spécifications! developer.android.com/guide/components/services.html#Foreground Un service de premier plan est un service dont l'utilisateur est activement conscient et qui n'est pas un candidat pour que le système tue lorsqu'il manque de mémoire.
IgorGanapolsky
3
@IgorGanapolsky La documentation est agréable, surtout si elle est complète et correcte (ce qui n'est malheureusement pas le cas), mais je me fie généralement davantage à des observations personnelles réelles. J'ai vu un premier plan Servicetué 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.
David Wasser du
@DavidWasser Observation juste. Alors après toutes ces années, avez-vous trouvé une solution?
IgorGanapolsky
@IgorGanapolsky Non. Je n'ai trouvé aucune solution à ce problème. C'est pourquoi la question est toujours ouverte.
David Wasser
7

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

Hirschen
la source
Je reçois'grep' is not recognized as an internal or external command, operable program or batch file.
Dale
Mais je l'ai fait dans la coquille 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.
Dale
6

Voici comment procéder dans Android Studio.

  1. Connectez votre appareil en mode débogage à votre ordinateur.
  2. Ouvrez l'application sur votre appareil et accédez à l'activité pour laquelle vous souhaitez tester le "Revenir d'entre les morts".
  3. Appuyez sur le bouton Accueil de votre appareil.
  4. Dans Android Studio, accédez à Moniteur Android -> Moniteurs et appuyez sur l'icône Terminer l'application.
  5. Maintenant, vous pouvez revenir à votre application via les applications récentes ou en cliquant sur l'icône du lanceur, le comportement a été le même dans mes tests.
dbar
la source
2
Cela n'aide pas. Je dois le faire par programme, dans une suite de tests. Mais merci quand même.
David Wasser
En outre, cette réponse est à peu près la même que la réponse de Mark.
David Wasser
Une idée comment faire cela via UIAutomator ou Espresso?
IgorGanapolsky
Je ne trouve pas Android Monitor - Monitors. Ça doit être quelque chose dont ils se sont débarrassés. Je suis sur la version 3.2.1
Dale
1
@Dale Android Device Monitor est obsolète dans Android Studio 3.1 et supprimé d'Android Studio 3.2.
Valgaal
5

Mettez 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

bouton Terminer

Maintenant, lancez votre application à partir du lanceur sur un appareil Android


EDIT: Selon Internet, ce qui suit fonctionne également:

 adb shell am kill [my-package-name]

EDIT from the future: quelque chose à noter, il y a eu un changement dans Android Studio 4.0, si vous utilisez à Runpartir d'AS, alors Terminateémettra un fichier Force 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).

EpicPandaForce
la source
Ceci est une réponse en double
Onik
@Onik Tous les autres ont un tas de peluches inutiles comme ddms et autres. Bien que techniquement oui, stackoverflow.com/a/41975750/2413303 dit la même chose. Je devrais peut-être ajouter des photos.
EpicPandaForce
Ce n'est pas utile. J'ai un faisceau de test et je ne peux pas exécuter ces actions à partir du faisceau de test. De plus, le comportement n'est pas le même que celui qui se produit lorsque Android arrête le processus.
David Wasser
the behaviour is not the same as what happens when Android kills the processoui c'est
EpicPandaForce
Ce processus me montre l'activité précédente, pas l'activité du moment où le bouton d'accueil est enfoncé.
Dale
2

Vous pouvez effectuer les étapes suivantes pour reproduire le comportement recherché:

  1. Ouvrez votre application, accédez à l'activité principale
  2. Utilisez le panneau de notification pour accéder à une autre application en plein écran (par exemple, aux paramètres système - dans le coin supérieur droit)
  3. Tuez votre processus de candidature
  4. Appuyez sur le bouton retour
Igor Kostomin
la source
1
Merci pour votre réponse mais cela ne m'est pas utile car j'ai besoin d'un moyen automatisé pour le faire, pour des tests automatisés.
David Wasser
Donc, c'est la seule méthode que j'ai trouvée simulerait en fait l'effacement de la mémoire Android et la suppression de votre application (mon niveau d'API est de 19, et je ne peux donc pas utiliser la commande send-trim-memory). D'autres commandes telles que adb shell am force-stop com.my.app.package ou kill, ne reproduiront pas le même processus exact qui suivra la procédure ci-dessus!
Mark Garcia
2

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.

MSpeed
la source
C'est effectivement la même chose que la solution déjà publiée - et rejetée - il y a un an. La seule différence semble être l'application utilisée pour le définir sur un émulateur, par rapport aux téléphones plus récents qui le prennent en charge.
Chris Stratton
1
Désolé, comme le dit Chris Stratton, c'est à peu près la même suggestion que l'autre réponse. Il ne s'agit pas des activités de finition Android. Il s'agit d'Android en train de tuer tout le processus (ce qu'il fait, assez régulièrement et efficacement, en particulier sur les appareils HTC exécutant Android 4.x).
David Wasser
6
Celui-ci est presque bon mais il ne tuera pas le processus, il détruit seulement l'activité. Qu'est-ce que ça veut dire? Votre activité sera ouverte avec savedInstanceState mais toutes les variables statiques sont toujours en cours. Après l'arrêt du processus, toutes les variables statiques sont également effacées.
Marquez le
1

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.

Monstieur
la source
Merci pour votre réponse mais cela ne m'est pas utile car j'ai besoin d'un moyen automatisé pour le faire, pour des tests automatisés.
David Wasser
Android ne tuera jamais votre processus si votre activité est actuellement au premier plan. Vous essayez de tester une condition qui ne se produira jamais. Si votre activité est en arrière-plan, alors son état a déjà été sauvegardé et il n'y a aucune différence entre le tuer manuellement et Android le tuer avec une mémoire insuffisante, c'est-à-dire que le processus est juste tué; il n'y a rien de spécial à propos d'une perte de mémoire faible. Lorsque la mémoire est à nouveau disponible, vos services persistants seront redémarrés (sauf sur 4.4) et lorsque vous appuyez sur l'icône ou la tâche récente, la pile et l'état d'activité seront restaurés.
Monstieur
3
Dans votre exemple, cela revient à l'activité C parce que vous avez tué le processus alors que l'activité D était visible à l'écran (cela ne se produira jamais même en cas de mémoire insuffisante) et que l'état de l'activité C a été enregistré car il est en arrière-plan. Votre processus ne sera tué que s'il n'est pas du tout au premier plan, c'est-à-dire que l'état de l'activité D aurait été sauvegardé quand il est passé en arrière-plan et sera donc restauré même si votre processus est tué. Afin d'effectuer vos tests sur chaque activité, vous DEVEZ envoyer l'application en arrière-plan avant de la tuer.
Monstieur
Qu'entendez-vous par ~ " et mettez d'abord l'application en arrière-plan "?
IgorGanapolsky du
1

Vous pouvez également vous connecter à votre appareil / émulateur à partir du terminal avec adb shell, puis obtenir le PID de votre processus avec ps | grep <your_package_nameet l'exécuter kill -9 <pid>. Ensuite, ouvrez votre application réduite à partir du sélecteur d'applications récentes et elle redémarrera la dernière activité

qbasso
la source
Est-ce la même chose qu'Android tue un processus dans des conditions de mémoire insuffisante? Je pense que OP voulait spécifiquement que ...
IgorGanapolsky
1
@IgorGanapolsky l'est théoriquement, bien que vous ne puissiez pas le faire sur un appareil réel s'il n'est pas enraciné.
Fran Marzoa
0

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 Activityest 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.

MaciejGórski
la source
0

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 ...

Emil Borconi
la source
0

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 ActivityRecordchamp 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 haveStatevaleur est falseentre l'activité onResume()est appelée et onStop()ou onSaveInstanceState()est appelée, selon la version cible de l'application.

Si je tue le processus, Android recrée le processus et crée ActivityC.

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.

Comment simuler Android en tuant mon processus

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 la onResume()méthode ActivityE , vous pouvez effectuer l'astuce suivante.

class TerminatorActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val isPrePie = applicationInfo.targetSdkVersion < Build.VERSION_CODES.P
        val callbacks = TerminatorLifecycleCallbacks(isPrePie)
        (applicationContext as Application).registerActivityLifecycleCallbacks(callbacks)
    }

    private class TerminatorLifecycleCallbacks(
        // Before P onSaveInstanceState() was called before onStop(), starting with P it's
        // called after
        // Used to schedule the death as app reports server that activity has stopped
        // after the latest of these was invoked
        private val isPrePie: Boolean
    ) : ActivityLifecycleCallbacksDefault {

        private val handler = Handler(Looper.getMainLooper())

        override fun onActivityPostStopped(activity: Activity) {
            if (isPrePie) {
                terminate()
            }
        }

        override fun onActivityPostSaveInstanceState(activity: Activity, outState: Bundle) {
            if (!isPrePie) {
                terminate()
            }
        }

        fun terminate() {
            handler.postDelayed(
                {
                    Process.killProcess(Process.myPid()) // This is the end... 
                },
                LAST_MILLIS
            )
        }

        companion object {
            // Let's wait for a while, so app can report and server can handle the update
            const val LAST_MILLIS = 100L
        }

    }

    private interface ActivityLifecycleCallbacksDefault : Application.ActivityLifecycleCallbacks {
        override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
        override fun onActivityStarted(activity: Activity) {}
        override fun onActivityResumed(activity: Activity) {}
        override fun onActivityPaused(activity: Activity) {}
        override fun onActivityStopped(activity: Activity) {}
        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
        override fun onActivityDestroyed(activity: Activity) {}
    }
}

Ensuite, commencez simplement TerminatorActivitylorsque 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 .

ivkil
la source