Android beendet einen Prozess, wenn er sich im Hintergrund befindet und das Betriebssystem entscheidet, dass es die Ressourcen (RAM, CPU usw.) benötigt. Ich muss in der Lage sein, dieses Verhalten während des Testens zu simulieren, damit ich sicherstellen kann, dass sich meine Anwendung korrekt verhält. Ich möchte dies auf automatisierte Weise tun können, damit ich testen kann, ob sich die Anwendung in diesem Fall korrekt verhält, was bedeutet, dass ich dies bei jeder Aktivität usw. testen muss.
Ich weiß, wie ich meinen Prozess beenden kann. Das ist nicht das Problem. Das Problem ist , dass , wenn ich meinen Prozess (mit DDMS, töten adb shell kill
, Process.killProcess()
usw.) Android nicht es die gleiche Art und Weise neu zu starten , dass es würde , wenn das Android OS es selbst getötet hatte.
Wenn das Android-Betriebssystem den Prozess abbricht (aufgrund von Ressourcenanforderungen), erstellt Android den Prozess neu, wenn der Benutzer zur Anwendung zurückkehrt, und erstellt dann die oberste Aktivität auf dem Aktivitätsstapel neu (Aufruf onCreate()
).
Wenn ich den Prozess hingegen abbrich, geht Android davon aus, dass sich die Aktivität oben auf dem Aktivitätsstapel schlecht verhalten hat. Daher wird der Prozess automatisch neu erstellt und anschließend die oberste Aktivität aus dem Aktivitätsstapel entfernt und die darunter liegende Aktivität neu erstellt die oberste Aktivität (Aufruf von onCreate () `). Dies ist nicht das Verhalten, das ich will. Ich möchte das gleiche Verhalten wie wenn Android den Prozess abbricht.
Nur um es bildlich zu erklären, wenn mein Aktivitätsstapel so aussieht:
ActivityA -> ActivityB -> ActivityC -> ActivityD
Wenn Android den Prozess abbricht und der Benutzer zur Anwendung zurückkehrt, erstellt Android den Prozess neu und erstellt ActivityD.
Wenn ich den Prozess abbreche, erstellt Android den Prozess neu und erstellt ActivityC.
Antworten:
Der beste Weg, dies für mich zu testen, war Folgendes:
Terminate Application
in Logcat Fenster in Android Studio (dies wird die App Prozess töten, stellen Sie sicher , wählen Sie Ihr Gerät und Verfahren in Logcat Aufklappmenü oben)Auf einigen Geräten können Sie auch über Anwendungen -> Ihr Startsymbol zur Anwendung (ActivityD) zurückkehren. Auf anderen Geräten wird stattdessen ActivityA gestartet.
Dies ist, was Android-Dokumente dazu sagen:
quelle
<activity>
Tag im Manifest handelt.Das scheint bei mir zu funktionieren:
Dies unterscheidet sich
adb shell kill
von der vom OP erwähnten.Beachten Sie, dass die Hilfe für den
am kill
Befehl lautet:Der Prozess wird also nicht abgebrochen, wenn er im Vordergrund steht. Dies scheint so zu funktionieren, wie es das OP wollte. Wenn ich von meiner App weg navigiere und sie dann ausführe
adb shell am kill <package_name>
, wird die App beendet (ich habe diesps
auf dem Gerät bestätigt). Wenn ich dann zur App zurückkehre, bin ich wieder in der Aktivität, in der ich zuvor war - dh im Beispiel des OP wird der Prozess neu erstellt und erstellt ActivityD (anstelle von ActivityC, wie es die meisten anderen Tötungsmethoden auslösen).Es tut mir leid, dass ich ein paar Jahre zu spät zum OP komme, aber hoffentlich finden andere dies nützlich.
quelle
adb shell am force-stop
. Der letzte entfernt auch alle anstehenden Inhalte, die mit Ihrer App zusammenhängen (wie Benachrichtigungen), während der erste dies nicht tut.am kill
.ps
zeigt meine AppEine andere Methode, wahrscheinlich eine, die skriptfähig ist, da sie kein DDMS erfordert:
Einmalige Einrichtung: Gehen Sie zu Entwickleroptionen, wählen Sie Einstellung für Hintergrundprozesslimit, ändern Sie den Wert von 'Standardlimit' in 'Keine Hintergrundprozesse'.
Wenn Sie den Vorgang neu starten müssen, drücken Sie die Home-Taste. Der Prozess wird abgebrochen (Sie können dies in logcat / Android Monitor in Studio überprüfen - der Prozess wird mit [DEAD] markiert). Wechseln Sie dann mit dem Task-Umschalter zurück zur App.
quelle
Diese Frage ist alt, aber es gibt eine Antwort auf diese Frage, für die kein ADB, Android Studio usw. erforderlich ist. Die einzige Anforderung ist API 23 oder neuer.
Um einen App-Neustart nach Betriebssystem zu simulieren, gehen Sie zu den App-Einstellungen, während Ihre App ausgeführt wird, deaktivieren Sie eine Berechtigung (dann können Sie sie aktivieren) und geben Sie die App von den letzten Apps zurück. Wenn die Berechtigung deaktiviert ist, beendet das Betriebssystem die App, behält jedoch die gespeicherten Instanzzustände bei. Wenn der Benutzer die App zurückgibt, werden die App und die letzte Aktivität (mit gespeichertem Status) neu erstellt.
Die Methode "Keine Hintergrundprozesse" verursacht manchmal dasselbe Verhalten, aber nicht immer. Wenn in der App beispielsweise ein Hintergrunddienst ausgeführt wird, führt "Keine Hintergrundprozesse" nichts aus. Die App kann jedoch vom System einschließlich seiner Dienste beendet werden. Die Berechtigungsmethode funktioniert auch dann, wenn die App über einen Dienst verfügt.
Beispiel:
Unsere App hat zwei Aktivitäten. AktivitätA ist die Hauptaktivität, die vom Launcher aus gestartet wird. Aktivität B wird von Aktivität A gestartet. Ich werde nur die Methoden onCreate, onStart, onStop und onDestroy anzeigen. Android ruft onSaveInstanceState immer vor dem Aufruf von onStop auf, da eine Aktivität, die sich im Stoppzustand befindet, vom System beendet werden kann. [ https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle]
Berechtigungsmethode:
Ich möchte andere Methoden vergleichen, die in den anderen Antworten erwähnt werden.
Aktivitäten nicht behalten: Dies beendet die Anwendung nicht.
Stop-Methode erzwingen: Speichert keine gespeicherten Instanzzustände
quelle
Service
oft getötet gesehen . Auch wenn das System nicht über genügend Speicher verfügt. Die meisten Gerätehersteller haben ihre eigenen "Optimierungen" und "Verbesserungen" für das Android-Betriebssystem geschrieben, um Batteriestrom zu sparen. Viele Geräte haben viel aggressivere "Killer" als Standard-Android.Ich bin sehr spät zur Party und einige vor mir gaben die gleiche richtige Antwort, aber um es für jeden zu vereinfachen, der nach mir kommt, drücken Sie einfach die Home-Taste und führen Sie diesen Befehl aus:
adb shell ps | grep <package name> | awk '{print $2}' | xargs adb shell run-as <package name again> kill
Die App verliert nicht den Status und meiner Erfahrung nach funktioniert dies genauso, wie das Betriebssystem die App im Hintergrund beendet hat. Dies funktioniert nur für Debug-Anwendungen
quelle
'grep' is not recognized as an internal or external command, operable program or batch file.
run-as <package name> kill 7379
, aber es hat mich zur vorherigen Aktivität gebracht, nicht zur Aktivität, bei der ich war, als ich den Home-Knopf gedrückt habe.So machen Sie es in Android Studio.
quelle
Android Monitor - Monitors
. Muss etwas sein, das sie losgeworden sind. Ich bin auf v 3.2.1Stellen Sie die Anwendung mit der HOME-Schaltfläche in den Hintergrund
Wählen Sie Ihren Prozess im "Logcat" -Modus in Android Studio aus und klicken Sie dann in der unteren linken Ecke auf "Anwendung beenden"
Starten Sie jetzt Ihre App vom Launcher auf einem Android-Gerät
EDIT: Laut Internet funktioniert auch folgendes:
BEARBEITEN aus der Zukunft: Es ist zu beachten, dass in Android Studio 4.0 eine Änderung vorgenommen wurde. Wenn Sie
Run
AS verwenden,Terminate
wird a ausgegebenForce Stop
.Wenn Sie jedoch anschließend vom Launcher aus starten und dann versuchen, dies auf diese Weise zu simulieren, erhalten Sie die gewünschten Ergebnisse (geringes Speicherverhalten).
quelle
the behaviour is not the same as what happens when Android kills the process
Ja, das ist esSie können die nächsten Schritte ausführen, um das gesuchte Verhalten zu reproduzieren:
quelle
Wählen Sie in den Entwickleroptionen unter "Einstellungen" die Option "Aktivitäten nicht beibehalten" aus. Dadurch werden Aktivitäten zerstört, sobald Sie von ihnen weg navigieren.
Hinweis: Verwenden Sie dies gemäß einem hilfreichen Kommentar unten nur, wenn Sie sich nicht darum kümmern, dass statische Werte gelöscht werden.
quelle
Drücken Sie die Home-Taste und stellen Sie die App zuerst in den Hintergrund. Stoppen oder beenden Sie dann den Prozess über DDMS oder ADB.
quelle
Sie können auch vom Terminal mit eine Verbindung zu Ihrem Gerät / Emulator herstellen
adb shell
, dann die PID Ihres Prozesses mitps | grep <your_package_name
abrufen und ausführenkill -9 <pid>
. Öffnen Sie dann Ihre minimierte App über die Auswahl der letzten Apps und die letzte Aktivität wird neu gestartetquelle
Die Wurzel Ihres Problems scheint zu sein, dass Sie
Activity
im Vordergrund stehen, wenn Sie den Prozess beenden.Sie können dies beobachten, indem Sie in DDMS auf Stopp drücken, wenn dies
Activity
sichtbar ist (passiert genau das, was Sie beschreiben) und dies mit dem Drücken von Stopp nach dem Start und dem späteren Zurückkehren zur App vergleichen.moveTaskToBack(true)
Stellen Sie einfach sicher, dass Sie in Ihren Tests irgendwie.quelle
Ich bin mir nicht sicher, ob dies die Antwort ist, nach der Sie suchen. Es ist eher ein logischer Gedanke.
Ich glaube nicht, dass Sie wirklich einen vollautomatischen Test durchführen können. Die einzige Möglichkeit, ihn zu simulieren, besteht darin, ihn neu zu erstellen. Die AKA hat so viele Aktivitäten, dass Android Ihre Anwendung beendet.
Meine Idee oder mein Vorschlag ist es also, eine weitere kleine App zu erstellen, die immer wieder neue Aktivitäten aufwirft, bis Android nicht mehr über genügend Speicher verfügt, und den Hintergrund im Hintergrund zu beenden.
Etwas in der Zeile:
Aktivität starten i -> Überprüfen Sie den laufenden Prozess, wenn die App in der Liste enthalten ist, erhöhen Sie i und starten Sie die Schleife neu, ohne die aktuelle Aktivität zu schließen. Andernfalls -> verringern Sie i und schließen Sie die aktuelle Aktivität, kehren Sie zur vorherigen zurück und überprüfen Sie erneut ...
quelle
Wenn der Bewerbungsprozess abbricht, durchläuft Android die Aktivitätsdatensätze (die Einträge stellen Aktivitäten im Verlaufsstapel dar) und entscheidet, welche im Verlauf gespeichert und welche aus dem Verlauf entfernt werden sollen.
Einer der wichtigsten Punkte ist das
ActivityRecord
FeldhaveState
, das von Android Framework-Ingenieuren als "Haben wir den letzten Aktivitätsstatus erhalten?" Beschrieben wird .Standardmäßig geht Android davon aus , dass die Aktivität einen Status hat. Die Aktivität wird zustandslos, wenn die Anwendung dem Aktivitäts-Task-Manager-Dienst meldet , dass die Aktivität wieder aufgenommen wurde. Dies gilt so lange, bis die Anwendung dem Framework mitteilt, dass die Aktivität in den Status Gestoppt versetzt wurde. In einfachen Worten, der
haveState
Wertfalse
zwischen AktivitätonResume()
wird aufgerufen und /onStop()
oderonSaveInstanceState()
aufgerufen, abhängig von der Anwendungszielversion.In diesem Fall hat ActivityD kein
android:stateNotNeeded="true"
Attribut im Anwendungsmanifest und wird derzeit im Vordergrund ausgeführt. Daher entfernt Android es aus dem Verlauf, da das System seinen letzten Status nicht erhalten hat.Wie bereits mehrfach erwähnt, können Sie die Anwendung einfach in den Hintergrund verschieben, sodass die oberste Aktivität im Aktivitäts-Backstack ihren Status speichert. Anschließend können Sie den Anwendungsprozess über Android Debug Bridge, Android Studio oder mithilfe von beenden Hintergrundprozesse Limit-Eigenschaft in den Entwickleroptionen. Danach wird Ihre letzte Aktivität erfolgreich neu erstellt.
Trotzdem gibt es noch eine andere einfache Möglichkeit, das Todesszenario des Anwendungsprozesses zu testen. Wenn Sie alle oben beschriebenen Punkte kennen und wissen, dass der ActivityD-
onStop()
Rückruf erst nach der ActivityE-onResume()
Methode aufgerufen wird, wenn Sie neue ActivityE über die aktuell ausgeführte ActivityD starten , können Sie den folgenden Trick ausführen.Starten
TerminatorActivity
Sie dann einfach, wenn Sie die Anwendung beenden möchten.Am Ende gibt es ein leichtes Tool namens Venom , das das Testen des Todes Ihres Bewerbungsprozesses vereinfacht .
quelle