Android niszczy działania, zabija procesy


117

Cześć, zastanawiam się, jak Android zarządza pamięcią i nigdzie nie mogę znaleźć dokładnej odpowiedzi. Załóżmy, że mam aplikację z 5 działaniami na bieżącym stosie aktywności (4 są zatrzymane, a 1 jest wznawiany), nie ma podłączonej usługi. Naciskam przycisk HOME, aby zatrzymać wszystkie moje czynności. Uruchamiam inną aplikację zużywającą pamięć i ogólna pamięć urządzenia zaczyna być niska. I pytanie brzmi

... Co się stanie z moją aplikacją?

  1. Czy system może zniszczyć tylko jedno lub kilka moich działań, aby odzyskać pamięć?
  2. Czy system zabije cały proces mojej aplikacji? Czy wszystkie działania zostaną ładnie zniszczone?
  3. Co się stanie, gdy wrócę do aplikacji, która została całkowicie usunięta? Czy zacznie od początku (tak jak przy pierwszym uruchomieniu), czy też spróbuje przywrócić czynności do stanu poprzedniego / jeśli tak - czy to tylko ta na szczycie stosu, czy wszystkie?

AKTUALIZACJA:

Zanim zadałem to pytanie, kilka razy widziałem cykl życia działania, ale nie ma on odpowiedzi na moje pytania. Zrobiłem kilka testów i mam kilka odpowiedzi. Wskazówką do testowania było „zatrzymanie procesu” w DDMS.

Nie testowałem odpowiedzi na pytanie 1, ale jako przewodnik mówi:

Jeśli czynność zostanie wstrzymana lub zatrzymana, system może usunąć ją z pamięci, prosząc ją o zakończenie lub po prostu zabijając jej proces.

Wydaje się, że jedną lub więcej aktywności można delikatnie (metodą onDestroy) zniszczyć bez przerywania procesu. Wracając do nich, po prostu otrzymasz (pakiet onCreate +).

Odpowiedź na pytanie 2:

TAK. Ogólnie system zabija cały proces, co oznacza, że ​​wszystkie dane, w tym działania i pola statyczne, są niszczone. NIE jest to zrobione ładnie - nie dostaniesz się na Destroy ani finialize () dla żadnej z wstrzymanych / zatrzymanych działań. Dlatego metoda saveInstanceState () jest wywoływana tuż przed metodą onPause. onPause jest w zasadzie ostatnią metodą, w której należy coś zapisać, ponieważ po tej metodzie nigdy nie można było zobaczyć onStop ani onDestroy. System może po prostu zabić proces, niszcząc wszystkie obiekty, niezależnie od tego, co przechowują i cokolwiek robią.

Odpowiedź na pytanie 3:

Co się stanie, gdy wrócisz do zawieszonej aplikacji?

  • Przed Androidem 2.2 - aplikacja będzie uruchamiana od początku, wraz z aktywnością programu uruchamiającego.
  • Począwszy od 2.2 - system przywróci poprzedni stan aplikacji. Co to znaczy? Oznacza to, że ostatnia widoczna aktywność zostanie odtworzona (pakiet onCreate +). Co się stanie ze stosem aktywności? Stos jest w porządku, ale wszystkie działania na nim są martwe. Każdy z nich zostanie odtworzony (pakiet onCreate +), gdy wrócisz do niego przyciskiem Wstecz. Jest jeszcze jedna rzecz:

Zwykle system czyści zadanie (usuwa wszystkie działania ze stosu nad działaniem roota) w pewnych sytuacjach, gdy użytkownik ponownie wybiera to zadanie na ekranie głównym. Zwykle dzieje się tak, jeśli użytkownik nie odwiedził zadania przez określony czas, na przykład 30 minut.

Wniosek?

  1. Nie myśl, że problemy z obsługą rotacji działań można rozwiązać za pomocą androida: configChanges = "orientacja". Kiedy to zrobisz, napotkasz wiele innych problemów, o których nawet nie jesteś świadomy.
  2. Przetestuj swoją aplikację za pomocą DDMS - przycisk zatrzymania procesu. Zobacz
  3. Zachowaj ostrożność podczas używania zmiennych statycznych. Nie myśl, że kiedy zainicjujesz je w ćwiczeniu 1 - zainicjujesz je w działaniu 2. Jedynym bezpiecznym miejscem do zainicjowania globalnej statystyki byłaby klasa Application.
  4. Pamiętaj, że możesz nigdy nie zobaczyć onStop lub onDestroy. Zamknij pliki / bazy danych, zatrzymaj programy do pobierania w trybie onPause. Jeśli chcesz, aby aplikacja coś zrobiła w BG - użyj usługi pierwszego planu.

To by było na tyle ... Mam nadzieję, że pomogłem w moim eseju :)


Zakładając, czy te 5 działań pochodzi z tej samej aplikacji, czy z kilku różnych aplikacji?
dumbfingers

1
„Mam aplikację z 5 działaniami na bieżącym stosie aktywności” Oczywiście wszystkie pochodzą z mojej, jednej, tej samej aplikacji procesowej.
Mark

4
Dziękuję, to też było moje pytanie ... Twoje pytanie i odpowiedzi bardzo mi pomogły.
craigrs84


@Mark: Czy ten problem został już rozwiązany? A jeśli tak jest?
Ameer Moaaviah

Odpowiedzi:


30

Najpierw spójrz na to:

img1

onPause () Wywoływana, gdy system ma wznowić poprzednie działanie. Jest to zwykle używane do zatwierdzania niezapisanych zmian w trwałych danych, zatrzymywania animacji i innych rzeczy, które mogą zużywać procesor itp. Implementacje tej metody muszą być bardzo szybkie, ponieważ następne działanie nie zostanie wznowione, dopóki ta metoda nie powróci. Następuje po nim onResume (), jeśli aktywność wraca na początek, lub onStop (), jeśli staje się niewidoczna dla użytkownika.

onStop () Wywoływana, gdy działanie nie jest już widoczne dla użytkownika, ponieważ inne działanie zostało wznowione i obejmuje to. Może się tak zdarzyć, gdy rozpoczyna się nowa czynność, poprzedza już istniejącą lub ta jest niszczona. Następnie następuje onRestart (), jeśli to działanie powraca do interakcji z użytkownikiem, lub onDestroy (), jeśli to działanie odchodzi.

Tak więc, gdy przycisk „Home” na urządzeniu naciśnięciu, aktualna aktywność planie kładzie się na onPause()potem onStop(), drugi 4 powinno pozostaćonStop()

Według dokumentów Google:

  • Jeśli działanie na pierwszym planie ekranu (na górze stosu) jest aktywne lub uruchomione.
  • Jeśli aktywność straciła ostrość, ale nadal jest widoczna (to znaczy nowe działanie o niepełnym rozmiarze lub przezroczyste skupia się na aktywności), zostaje wstrzymane. Wstrzymana aktywność jest całkowicie aktywna (zachowuje wszystkie informacje o stanie i członkach oraz pozostaje połączona z menedżerem okien), ale może zostać zabita przez system w sytuacjach skrajnie małej ilości pamięci.
  • Jeśli czynność jest całkowicie zasłonięta przez inną czynność, zostaje zatrzymana. Nadal zachowuje wszystkie informacje o stanie i członkach, jednak nie jest już widoczne dla użytkownika, więc jego okno jest ukryte i często jest zabijane przez system, gdy pamięć jest potrzebna w innym miejscu.
  • Jeśli czynność zostanie wstrzymana lub zatrzymana, system może usunąć ją z pamięci, prosząc ją o zakończenie lub po prostu zabijając jej proces. Gdy zostanie ponownie wyświetlony użytkownikowi, należy go całkowicie zrestartować i przywrócić do poprzedniego stanu.

A dla cyklu życia procesu:

Cykl życia procesu 3. Działanie w tle (działanie, które nie jest widoczne dla użytkownika i zostało wstrzymane) nie jest już krytyczne, więc system może bezpiecznie zakończyć swój proces, aby odzyskać pamięć dla innych procesów pierwszoplanowych lub widocznych. Jeśli jego proces musi zostać zabity, gdy użytkownik przejdzie z powrotem do działania (sprawiając, że będzie on ponownie widoczny na ekranie), jego metoda onCreate (Bundle) zostanie wywołana z wartością saveInstanceState, którą wcześniej dostarczyła w onSaveInstanceState (Bundle), aby może uruchomić się ponownie w tym samym stanie, w jakim ostatnio go opuścił użytkownik.

Wszystkie powyższe cytaty pochodzą z: Materiały referencyjne dla programistów Androida: Aktywność

Potwierdzono, że system może niszczyć nieczynne czynności i odtwarzać wspomnienia po uruchomieniu niektórych aplikacji zużywających pamięć. I możesz zaimplementować takie działania jak: isFinishing()w swojej aktywności, a następnie używając przycisku „zabij” w DDMS, aby wykryć, które z Twoich działań są odrzucane przez system. Ale myślę, że system najpierw zniszczy najstarszy. Jednak nie ma sensu zatrzymywanie innych działań, gdy „Uruchomienie działania” zostało poddane recyklingowi.

AKTUALIZACJA

Oto kilka opinii, które znalazłem tutaj :

Stan zatrzymany

Kiedy działanie nie jest widoczne, ale nadal jest w pamięci, mówimy, że jest w stanie zatrzymania. Zatrzymaną aktywność można przywrócić na pierwszy plan, aby ponownie stać się aktywnością Bieganie. Lub może zostać zniszczone i usunięte z pamięci.

System utrzymuje działania w stanie zatrzymanym, ponieważ jest prawdopodobne, że użytkownik nadal będzie chciał wrócić do tych działań wkrótce, a ponowne uruchomienie zatrzymanej czynności jest znacznie tańsze niż rozpoczęcie działania od zera. Dzieje się tak, ponieważ mamy już wszystkie obiekty załadowane do pamięci i po prostu musimy przenieść to wszystko na pierwszy plan.

Zatrzymane działania można w dowolnym momencie usunąć z pamięci.


4
Dokumentacja jest dość zagmatwana w tej kwestii, jednak można zabić tylko cały proces, a nie poszczególne komponenty (czynności, usługi itp.). Zobacz: stackoverflow.com/questions/7536988/…
greg7gkb

To pytanie powinno zostać zaktualizowane o informacje w linku do komentarza @ greg7gkb, jego mylące
Luke De Feo

1

Czy system może zniszczyć tylko jedno lub kilka moich działań, aby odzyskać pamięć?

Tak. Android zabija czynności wykonywane w tle, gdy istnieje potrzeba pamięci. Zabicie jednego lub wszystkich może zależeć od pewnych warunków. Na przykład wstrzymanie lub zatrzymanie może spowodować, że android zabi działanie lub sam proces. Tutaj w ramach cyklu życia działania możesz uzyskać poniższe punkty. Zalecam ci pełne przejrzenie tej strony. Z pewnością rozwiąże Twoje wątpliwości.

Jeśli aktywność straciła ostrość, ale nadal jest widoczna (to znaczy nowe, niepełne lub przezroczyste działanie skupia się na aktywności), zostaje wstrzymane. Wstrzymana aktywność jest całkowicie aktywna (zachowuje wszystkie informacje o stanie i członkach oraz pozostaje połączona z menedżerem okien), ale może zostać zabita przez system w sytuacjach skrajnie małej ilości pamięci.

Jeśli czynność jest całkowicie zasłonięta przez inną czynność, zostaje zatrzymana. Nadal zachowuje wszystkie informacje o stanie i członkach, jednak nie jest już widoczny dla użytkownika, więc jego okno jest ukryte i często jest zabijane przez system, gdy pamięć jest potrzebna w innym miejscu.

Jeśli czynność zostanie wstrzymana lub zatrzymana, system może usunąć ją z pamięci, prosząc ją o zakończenie lub po prostu zabijając jej proces. Gdy zostanie ponownie wyświetlony użytkownikowi, należy go całkowicie zrestartować i przywrócić do poprzedniego stanu.


Czy system zabije cały proces mojej aplikacji? Czy wszystkie działania zostaną ładnie zniszczone?

Czynność dotyczy jednostki, a proces - grupy czynności. Spójrz na trzeci punkt powyżej, ponownie zabija proces, jak wspomniano.


Co się stanie, gdy wrócę do aplikacji, która została całkowicie usunięta?

Jest podobny do ponownego uruchomienia. Znowu trzeci punkt da ci kilka odpowiedzi, takich jakWhen it is displayed again to the user, it must be completely restarted and restored to its previous state

Uzyskaj więcej informacji na temat rzeczy związanych z pamięcią tutaj .

Edycja:
wszystkie działania w aplikacji są wykonywane w jednym procesie. Więc kiedy proces zostanie zabity, wszystkie działania bez względu na 5 czy 10 zostaną zabite, tj. Ponownie uruchomione. Ponowne uruchomienie spowoduje, że aplikacja rozpocznie się od początku bez zapisanych stanów.


2
Widziałem Cykl Życia Aktywności co najmniej 5 razy, ale to nie odpowiada na moje pytania. To, co powiedziałeś, oznaczałoby, że mój proces aplikacji zostanie zabity - kiedy wrócę do aplikacji, zostanie przywrócony do poprzedniego stanu. Więc kiedy miałem 5 zatrzymanych czynności ... czy wszystkie umarły (wywołane onDestroy), kiedy proces został zabity? Kiedy wróciłem do mojej aplikacji, czy wszystkie działania zostały przywrócone (pakiet onCreate +), czy tylko ta na szczycie stosu (widoczna dla użytkownika)?
Mark

1
Wszystkie działania w aplikacji są wykonywane w jednym procesie. Więc kiedy proces zostanie zabity, wszystkie działania bez względu na 5 czy 10 zostaną zabite, tj. Ponownie uruchomione. Ponowne uruchomienie spowoduje uruchomienie aplikacji od początku brak zapisanych stanów ..
Vinay

1
Prawie prawda, ale nie w wersji 2.2 i nowszych. Zobacz moją AKTUALIZACJĘ u góry strony.
Mark

1
Nie, to nieprawda i nigdy nie była prawdą. Na podstawie dokumentacji jest to mylące, ale zobacz: stackoverflow.com/questions/7536988/ ...
greg7gkb

2
@JJPA Android nie może zniszczyć pojedynczych działań w celu odzyskania pamięci, niszczy tylko procesy. Zobacz odpowiedź Dianne Hackbor, członka podstawowego zespołu Androida zaangażowanego w implementację „zabójcy braku pamięci”: stackoverflow.com/a/7576275/1290264 .
bcorso
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.