Android zabije proces, jeśli będzie działał w tle, a system operacyjny zdecyduje, że potrzebuje zasobów (RAM, procesor itp.). Muszę móc symulować to zachowanie podczas testowania, aby upewnić się, że moja aplikacja działa poprawnie. Chcę móc to robić w sposób zautomatyzowany, aby móc sprawdzić, czy aplikacja zachowuje się poprawnie, ilekroć tak się stanie, co oznacza, że będę musiał to testować w każdym działaniu itp.
Wiem, jak zabić swój proces. To nie jest problem. Problem polega na tym, że kiedy zabić mojego procesu (stosując DDMS, adb shell kill
, Process.killProcess()
, itd.) Android nie uruchomić go w ten sam sposób, że jeżeli będzie Android OS zabił sama.
Jeśli system operacyjny Android zabije proces (ze względu na wymagania dotyczące zasobów), gdy użytkownik wróci do aplikacji, system Android odtworzy proces, a następnie ponownie utworzy najwyższą aktywność na stosie aktywności (wywołanie onCreate()
).
Z drugiej strony, jeśli ja zabić proces, Android zakłada, że działalność na wierzchu stosu aktywność była źle wychowane , więc automatycznie odtwarza proces, a następnie usuwa aktywność top ze stosu działalności i odtwarza czynność, która była pod spodem najważniejsze działanie (wywołanie onCreate () `). Nie jest to zachowanie, którego chcę. Chcę takiego samego zachowania, jak wtedy, gdy Android zabija proces.
Aby wyjaśnić obrazowo, jeśli mój stos aktywności wygląda następująco:
ActivityA -> ActivityB -> ActivityC -> ActivityD
Jeśli system Android zabije proces, a użytkownik wróci do aplikacji, system Android ponownie utworzy proces i utworzy ActivityD.
Jeśli zabiję proces, Android odtwarza proces i tworzy ActivityC.
Odpowiedzi:
Najlepszym sposobem, aby to przetestować, było zrobienie tego:
Terminate Application
w oknie Logcat w Android Studio (spowoduje to zabicie procesu aplikacji, upewnij się, że wybierasz swoje urządzenie i proces w menu rozwijanym Logcat u góry)Na niektórych urządzeniach możesz również wrócić do aplikacji (ActivityD) za pomocą aplikacji -> ikona programu uruchamiającego, ale na innych urządzeniach zamiast tego uruchomi się ActivityA.
Oto, co mówią na ten temat dokumentacja Androida:
źródło
<activity>
tagu w manifeście.To wydaje się działać dla mnie:
Różni się to od
adb shell kill
wspomnianego w PO.Zwróć uwagę, że pomoc do
am kill
polecenia mówi:Tak więc nie zabije procesu, jeśli znajduje się na pierwszym planie. Wydaje się, że działa to tak, jak chciał OP, ponieważ jeśli opuszczę moją aplikację, a następnie uruchomię
adb shell am kill <package_name>
ją, zabije aplikację (potwierdziłem tops
na urządzeniu). Następnie, jeśli wrócę do aplikacji, wrócę do działania, w którym byłem wcześniej - tj. W przykładzie OP proces zostaje odtworzony i tworzy ActivityD (zamiast ActivityC, jak większość innych metod zabijania wydaje się wyzwalać).Przepraszam, że spóźniłem się kilka lat na OP, ale mam nadzieję, że inni uznają to za przydatne.
źródło
adb shell am force-stop
. Ta ostatnia usunie również wszystkie oczekujące Intencje związane z Twoją aplikacją (takie jak Powiadomienia), podczas gdy pierwsza nie.am kill
.ps
pokazuje moją aplikacjęInna metoda, prawdopodobnie taka, która jest skryptowalna, ponieważ nie wymaga DDMS:
Konfiguracja jednorazowa: przejdź do opcji programisty, wybierz ustawienie limitu procesów w tle, zmień wartość z „Standardowy limit” na „Brak procesów w tle”.
Kiedy musisz ponownie uruchomić proces, naciśnij przycisk home. Proces zostanie zabity (możesz to sprawdzić w logcat / Android Monitor w studio - proces zostanie oznaczony jako [DEAD]). Następnie wróć do aplikacji za pomocą przełącznika zadań.
źródło
To pytanie jest stare, ale istnieje na nie odpowiedź, która nie wymaga adb, Android Studio itp. Jedynym wymaganiem jest API 23 lub nowsze.
Aby zasymulować ponowne uruchomienie aplikacji przez system operacyjny, przejdź do ustawień aplikacji, gdy aplikacja jest uruchomiona, wyłącz (a następnie możesz włączyć) uprawnienia i zwróć aplikację z ostatnich aplikacji. Gdy uprawnienia są wyłączone, system operacyjny zabija aplikację, ale zachowuje zapisane stany instancji. Gdy użytkownik zwraca aplikację, aplikacja i ostatnia aktywność (z zapisanym stanem) są odtwarzane.
Metoda „bez procesów w tle” czasami powoduje to samo zachowanie, ale nie zawsze. Na przykład, jeśli aplikacja działa w tle, „Brak procesów w tle” nic nie robi. Ale aplikacja może zostać zabita przez system, w tym jego usługi. Metoda uprawnień działa, nawet jeśli aplikacja ma usługę.
Przykład:
Nasza aplikacja ma dwa rodzaje aktywności. Działanie A jest głównym działaniem, które jest uruchamiane z programu uruchamiającego. AktywnośćB rozpoczyna się od Aktywności A. Pokażę tylko metody onCreate, onStart, onStop, onDestroy. Android wywołuje onSaveInstanceState zawsze przed wywołaniem onStop, ponieważ działanie, które jest w stanie zatrzymania, może zostać zabite przez system. [ https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle]
Metoda pozwolenia:
Chcę porównać inne metody, które są wymienione w innych odpowiedziach.
Nie zachowuj działań: nie powoduje to zabicia aplikacji.
Metoda wymuszania zatrzymania: nie przechowuje zapisanych stanów instancji
źródło
Service
zabijanie pierwszego planu . Nawet jeśli w systemie nie brakuje pamięci. Większość producentów urządzeń napisała własne „optymalizacje” i „ulepszenia” systemu operacyjnego Android w celu oszczędzania energii baterii. Wiele urządzeń ma znacznie bardziej agresywnych „zabójców” niż standardowy Android.Jestem bardzo spóźniony na imprezę i kilka przede mną dało tę samą poprawną odpowiedź, ale aby uprościć to, kto przyjdzie po mnie, po prostu naciśnij przycisk home i uruchom to polecenie:
adb shell ps | grep <package name> | awk '{print $2}' | xargs adb shell run-as <package name again> kill
Aplikacja nie straci stanu iz własnego doświadczenia działa to tak samo, jak system operacyjny zabił aplikację w tle. Działa to tylko w przypadku aplikacji do debugowania
źródło
'grep' is not recognized as an internal or external command, operable program or batch file.
run-as <package name> kill 7379
, ale przeniosło mnie do poprzedniej czynności, a nie do czynności, w której byłem, kiedy nacisnąłem przycisk Home.Tak to się robi w Android Studio.
źródło
Android Monitor - Monitors
. To musi być coś, czego się pozbyli. Jestem w wersji 3.2.1Umieść aplikację w tle za pomocą przycisku HOME
Wybierz proces w trybie „Logcat” w Android Studio, a następnie kliknij Zakończ aplikację w lewym dolnym rogu
Teraz uruchom aplikację z programu uruchamiającego na urządzeniu z Androidem
EDYCJA: Według internetu działa również:
EDYCJA z przyszłości: Coś do odnotowania, nastąpiła zmiana w Android Studio 4.0, jeśli używasz
Run
z AS, toTerminate
wyda plikForce Stop
.Jeśli jednak później uruchomisz program uruchamiający, a NASTĘPNIE spróbujesz to zasymulować w ten sposób, uzyskasz pożądane wyniki (zachowanie małej ilości pamięci).
źródło
the behaviour is not the same as what happens when Android kills the process
tak, to jestMożesz wykonać kolejne kroki, aby odtworzyć pożądane zachowanie:
źródło
W opcjach programisty w Ustawieniach wybierz „Nie zachowuj działań”, co spowoduje zniszczenie działań, gdy tylko odejdziesz od nich.
Uwaga: zgodnie z pomocnym komentarzem poniżej, używaj tego tylko wtedy, gdy nie zależy Ci na czyszczeniu wartości statycznych.
źródło
Naciśnij przycisk Początek i najpierw umieść aplikację w tle. Następnie zatrzymaj lub zakończ proces z DDMS lub ADB.
źródło
Możesz także połączyć się ze swoim urządzeniem / emulatorem z terminala za pomocą
adb shell
, a następnie uzyskać PID swojego procesups | grep <your_package_name
i wykonaćkill -9 <pid>
. Następnie otwórz zminimalizowaną aplikację z selektora ostatnich aplikacji i uruchom ponownie ostatnią aktywnośćźródło
Wydaje się, że źródłem twojego problemu jest to, że jesteś
Activity
na pierwszym planie, gdy zabijasz proces.Możesz to zaobserwować, naciskając przycisk zatrzymania w DDMS, gdy
Activity
jest widoczny (dzieje się dokładnie tak, jak opisujesz ) i porównując to z naciśnięciem przycisku zatrzymania po powrocie do domu i późniejszym powrotem do aplikacji.Po prostu upewnij się, że
moveTaskToBack(true)
jakoś w swoich testach.źródło
Nie jestem pewien, czy to jest odpowiedź, której szukasz, to bardziej jak myślenie logiczne.
Nie sądzę, że naprawdę można wykonać w pełni zautomatyzowany test, jedynym sposobem na jego symulację będzie jego odtworzenie, AKA ma tak wiele działań, że Android zabije twoją aplikację.
Więc moim pomysłem lub sugestią jest zrobienie kolejnej małej aplikacji, która ciągle wyskakuje nowe działania, dopóki Androidowi nie zabraknie pamięci i zacznie zabijać proces w tle.
Coś wśród linii:
Rozpocznij czynność i -> Sprawdź uruchomiony proces, czy aplikacja znajduje się na liście, zwiększ i ponownie uruchom pętlę bez zamykania bieżącej czynności, w przeciwnym razie -> zmniejsz i i zamknij bieżącą czynność, wróć do poprzedniej i sprawdź ponownie ...
źródło
Kiedy proces aplikacji kończy się, Android przegląda rekordy działań (wpisy reprezentują działania na stosie historii) i podejmuje decyzję które z nich zachować w historii, a które usunąć z niej.
Jednym z kluczowych punktów jest tutaj
ActivityRecord
zwane polehaveState
, które inżynierowie Android Framework opisują jako „czy uzyskaliśmy ostatni stan aktywności?”.Domyślnie system Android uważa, że aktywność ma stan. Aktywność staje się bezstanowa, gdy aplikacja zgłasza do usługi menedżera zadań działań, że działanie zostało wznowione i jest to ważne, dopóki aplikacja nie powiadomi struktury, że działanie weszło w stan zatrzymania. W prostych słowach,
haveState
wartość znajduje sięfalse
między aktywnościąonResume()
jest wywoływana i /onStop()
lubonSaveInstanceState()
jest wywoływana, w zależności od wersji docelowej aplikacji.W tym przypadku ActivityD nie ma
android:stateNotNeeded="true"
atrybutu w manifeście aplikacji i obecnie działa na pierwszym planie, więc Android usuwa go z historii, ponieważ system nie uzyskał ostatniego stanu.Jak już kilkakrotnie wspominano, wystarczy po prostu przenieść aplikację w tło, dzięki czemu najwyższa aktywność w stosie aktywności zapisze jej stan, a następnie można zabić proces aplikacji za pomocą Android Debug Bridge, Android Studio lub za pomocą Właściwość Limit procesów w tle w Opcjach programisty. Następnie Twoja ostatnia aktywność zostanie pomyślnie odtworzona.
Mimo to istnieje również inny prosty sposób na przetestowanie scenariusza śmierci procesu aplikacji. Znając wszystkie opisane powyżej i fakt, że jeśli uruchomisz nowe ActivityE z aktualnie uruchomionego ActivityD, wtedy
onStop()
wywołanie zwrotne ActivityD zostanie wywołane dopiero poonResume()
metodzie ActivityE , możesz wykonać następującą sztuczkę.Następnie po prostu zacznij,
TerminatorActivity
gdy chcesz zabić aplikację.Na końcu znajduje się lekkie narzędzie, które upraszcza testowanie śmierci procesu aplikacji, zwane Venom .
źródło