W końcu przejdzie to do twojego pytania, ale najpierw chcę rozwiązać kilka kwestii poruszonych w różnych komentarzach do różnych odpowiedzi udzielonych już w momencie pisania tego tekstu. Nie mam zamiaru zmieniać zdania - są one raczej przeznaczone dla innych osób, które będą czytać ten post w przyszłości.
Chodzi o to, że nie mogę pozwolić, aby Android określił, kiedy moja aplikacja ma zostać zakończona. taki musi być wybór użytkownika.
Miliony ludzi są całkowicie zadowolone z modelu, w którym środowisko zamyka aplikację w razie potrzeby. Ci użytkownicy po prostu nie myślą o „zakończeniu” aplikacji na Androida, podobnie jak o „zakończeniu” strony internetowej lub „zakończeniu” termostatu.
Użytkownicy iPhone'a są w podobny sposób, ponieważ naciśnięcie przycisku iPhone'a niekoniecznie „czuje”, że aplikacja została zakończona, ponieważ wiele aplikacji iPhone'a odbiera miejsce, w którym użytkownik przerwał, nawet jeśli aplikacja naprawdę została zamknięta (ponieważ tylko iPhone obecnie umożliwia korzystanie z jednej aplikacji innej firmy).
Jak powiedziałem powyżej, w mojej aplikacji dzieje się wiele rzeczy (dane są PUSHed do urządzenia, listy z zadaniami, które zawsze powinny tam być, itp.).
Nie wiem, co oznaczają „listy z zadaniami, które zawsze powinny tam być”, ale „dane przekazywane do urządzenia” to przyjemna fikcja i w żadnym wypadku nie powinny być wykonywane przez działanie. Użyj zaplanowanego zadania (via AlarmManager
), aby zaktualizować dane w celu uzyskania maksymalnej niezawodności.
Nasi użytkownicy logują się i nie mogą robić tego za każdym razem, gdy otrzymają telefon, a Android zdecyduje się zabić aplikację.
Jest wiele aplikacji na iPhone'a i Androida. Zwykle dzieje się tak, ponieważ utrzymują oni poświadczenia logowania, a nie zmuszają użytkowników do logowania za każdym razem ręcznie.
Na przykład chcemy sprawdzić aktualizacje przy wychodzeniu z aplikacji
To błąd w każdym systemie operacyjnym. Z tego, co wiesz, przyczyną „zamknięcia” aplikacji jest zamknięcie systemu operacyjnego, a następnie proces aktualizacji zakończy się niepowodzeniem w połowie strumienia. Ogólnie rzecz biorąc, to nie jest dobra rzecz. Sprawdź aktualizacje przy starcie lub sprawdź aktualizacje całkowicie asynchronicznie (np. Poprzez zaplanowane zadanie), nigdy przy wyjściu.
Niektóre komentarze sugerują, że naciśnięcie przycisku Wstecz wcale nie zabija aplikacji (patrz link w moim pytaniu powyżej).
Naciśnięcie przycisku WSTECZ nie powoduje „zabicia aplikacji”. Kończy działanie, które było na ekranie, gdy użytkownik nacisnął przycisk WSTECZ.
Powinien on zostać zakończony tylko wtedy, gdy użytkownicy chcą go rozwiązać - nigdy w żaden inny sposób. Jeśli nie możesz pisać takich aplikacji w Androidzie, myślę, że Androida nie można używać do pisania prawdziwych aplikacji = (
Zatem aplikacje sieciowe również nie mogą. Lub WebOS , jeśli dobrze rozumiem ich model (jeszcze nie miałem okazji z nim grać). We wszystkich z nich użytkownicy niczego nie „kończą” - po prostu wychodzą. iPhone jest nieco inny, ponieważ obecnie pozwala tylko na uruchamianie jednej rzeczy naraz (z kilkoma wyjątkami), a zatem opuszczenie aplikacji oznacza dość natychmiastowe zakończenie aplikacji.
Czy istnieje sposób, aby naprawdę zamknąć aplikację?
Jak wszyscy ci mówili, użytkownicy (przez POWRÓT) lub kod (przez finish()
) mogą zamknąć bieżącą aktywność. Użytkownicy zwykle nie potrzebują niczego więcej, do poprawnie napisanych aplikacji, bardziej niż potrzebują opcji „wyjdź” do korzystania z aplikacji internetowych.
Z definicji nie ma dwóch takich samych środowisk aplikacji. Oznacza to, że możesz obserwować trendy w środowiskach, gdy pojawiają się nowe, a inne zostają pochowane.
Na przykład rośnie ruch próbujący wyeliminować pojęcie „pliku”. Większość aplikacji internetowych nie zmusza użytkowników do myślenia o plikach. Aplikacje iPhone zazwyczaj nie zmuszają użytkowników do myślenia o plikach. Aplikacje na Androida zazwyczaj nie zmuszają użytkowników do myślenia o plikach. I tak dalej.
Podobnie rośnie ruch próbujący wyeliminować pojęcie „zakończenia” aplikacji. Większość aplikacji sieci Web nie wymusza wylogowania użytkownika, ale domyślnie wylogowuje użytkownika po okresie bezczynności. To samo dotyczy Androida i, w mniejszym stopniu, iPhone'a (i ewentualnie WebOS).
Wymaga to większego nacisku na projektowanie aplikacji, koncentrowanie się na celach biznesowych i nieprzestrzeganie modelu implementacji powiązanego z poprzednim środowiskiem aplikacji. Programiści, którym brakuje czasu lub ochoty na zrobienie tego, będą sfrustrowani nowszymi środowiskami, które łamią istniejący model mentalny. Nie jest to wina żadnego środowiska, podobnie jak wina góry, a nie burz, które przepływają wokół niej.
Na przykład w niektórych środowiskach programistycznych, takich jak Hypercard i Smalltalk, aplikacja i narzędzia programistyczne były połączone w jednym zestawie. Ta koncepcja nie przyciągnęła zbyt wiele, poza rozszerzeniami językowymi aplikacji (np. VBA w Excelu , Lisp w AutoCAD ). Programiści, którzy wymyślili modele mentalne, które zakładały istnienie narzędzi programistycznych w samej aplikacji, musieli zatem zmienić swój model lub ograniczyć się do środowisk, w których ich model byłby prawdziwy.
Kiedy piszesz:
Wraz z innymi bałaganami, które odkryłem, myślę, że opracowanie naszej aplikacji na Androida nie nastąpi.
To wydaje się być najlepsze dla ciebie, na teraz. Podobnie odradzałbym ci próbę przeniesienia aplikacji do sieci, ponieważ niektóre z tych samych problemów, które zgłosiłeś z Androidem, znajdziesz również w aplikacjach internetowych (np. Brak „zakończenia”). Albo odwrotnie, jeśli kiedyś zrobić portu aplikacji do sieci, może się okazać, że przepływ aplikacji sieci Web mogą być lepiej dopasowane do Androida i można ponownie port Androida w tym czasie.
killProcess()
. Jest to ważny powód, aby pisać lepszy kod iOS.Chciałbym tylko dodać tutaj poprawkę dla przyszłych czytelników tego wątku. Ten szczególny niuans umknął mi przez długi czas, dlatego chcę się upewnić, że nikt z was nie popełni takich samych błędów:
System.exit()
nie zabija Twojej aplikacji, jeśli masz więcej niż jedno działanie na stosie. W rzeczywistości proces jest zabijany i natychmiast uruchamiany ponownie z jedną mniejszą aktywnością na stosie. To samo dzieje się, gdy twoja aplikacja zostanie zabita przez okno Wymuś zamknięcie lub nawet gdy spróbujesz zabić proces z DDMS. Według mojej wiedzy jest to całkowicie nieudokumentowane.Krótka odpowiedź brzmi: jeśli chcesz wyjść z aplikacji, musisz śledzić wszystkie działania na stosie i
finish()
WSZYSTKIE z nich, gdy użytkownik chce wyjść (i nie, nie ma sposobu na iterację przez stos działań , więc musisz sam sobie z tym wszystkim poradzić). Nawet to tak naprawdę nie zabija procesu ani żadnych wiszących referencji. Po prostu kończy działania. Nie jestem też pewien, czyProcess.killProcess(Process.myPid())
działa lepiej; Nie testowałem tego.Jeśli z drugiej strony możesz pozostawać na stosie, możesz skorzystać z innej metody, która sprawia, że wszystko jest dla ciebie bardzo łatwe:
Activity.moveTaskToBack(true)
po prostu opisze proces i wyświetli ekran główny.Długa odpowiedź obejmuje wyjaśnienie filozofii tego zachowania. Filozofia zrodziła się z szeregu założeń:
onSaveInstanceState
, ale co zrobisz?) W przypadku większości dobrze napisanych aplikacji na Androida powinno to być prawdą, ponieważ nigdy nie wiadomo, kiedy aplikacja zostanie zabita w tle.Kiedy myślisz o tym, jest to odpowiednie dla platformy. Po pierwsze, dokładnie tak się dzieje, gdy proces jest zabijany w tle, a użytkownik do niego wraca, więc należy go ponownie uruchomić w miejscu, w którym został przerwany. Po drugie, dzieje się tak, gdy aplikacja ulega awarii i wyświetla przerażające okno dialogowe Force Close.
Powiedz, że chcę, aby moi użytkownicy mogli zrobić zdjęcie i przesłać je. Z mojej aktywności uruchamiam Aktywność kamery i proszę o zwrócenie obrazu. Kamera jest umieszczana na górze mojego bieżącego zadania (zamiast być tworzona we własnym zadaniu). Jeśli w aparacie wystąpił błąd i ulega awarii, czy powinno to spowodować awarię całej aplikacji? Z punktu widzenia użytkownika tylko kamera uległa awarii i należy ją przywrócić do poprzedniej aktywności. Więc po prostu restartuje proces z tymi samymi Aktywnościami na stosie, minus Kamera. Ponieważ Twoje działania powinny być zaprojektowane tak, aby można je było zabijać i przywracać za jednym razem, nie powinno to stanowić problemu. Niestety nie wszystkie aplikacje można tak zaprojektować, więc tak jest stanowić problem dla wielu z nas, bez względu na to, co powie Ci Romain Guy lub ktokolwiek inny. Musimy więc zastosować obejścia.
Tak więc moja rada na zakończenie:
finish()
do wszystkich czynności lub zadzwońmoveTaskToBack(true)
.startActivity()
z intencją, która zawieraIntent.FLAG_ACTIVITY_CLEAR_TOP
flagę.źródło
moveTaskToBack()
tego szukałem). Tak wiele osób mówi tylko: „Nie, jesteś idiotą, który chce wyjść z aplikacji”. nawet nie biorąc pod uwagę, że mogą istnieć przypadki, w których chcesz (np. nieudane logowanie).Wszystkie moje aplikacje mają przyciski zamykania ... i dość często otrzymuję pozytywne komentarze od użytkowników z tego powodu. Nie obchodzi mnie, czy platforma została zaprojektowana w taki sposób, że aplikacje nie powinny ich potrzebować. Mówienie „nie umieszczaj ich tam” jest trochę śmieszne. Jeśli użytkownik chce odejść ... Zapewniam mu dostęp do robienia dokładnie tego. Nie sądzę, żeby to w ogóle zmniejszyło działanie Androida i wydaje się dobrą praktyką. Rozumiem cykl życia ... i spostrzegłem, że Android nie radzi sobie z nim dobrze ... i to jest podstawowy fakt.
źródło
Przestań myśleć o swojej aplikacji jako aplikacji monolitycznej. Jest to zestaw ekranów interfejsu użytkownika, w których użytkownik może wchodzić w interakcje z „aplikacją” i „funkcjami” udostępnianymi za pośrednictwem usług Androida.
Nieznajomość tego, co „tajemnicza aplikacja” robi, nie jest tak naprawdę ważna. Załóżmy, że tuneluje się do super bezpiecznego korporacyjnego intranetu, wykonując pewne monitorowanie lub interakcję i pozostaje zalogowany, dopóki użytkownik „nie opuści aplikacji”. Ponieważ zarządza nim dział IT, użytkownicy muszą być bardzo świadomi tego, kiedy znajdują się w sieci intranet lub poza nią. Dlatego też sposób, w jaki użytkownicy powinni „rzucić”, jest ważny.
To jest proste. Wykonaj usługę, która umieszcza bieżące powiadomienie na pasku powiadomień z informacją: „Jestem w intranecie lub działam”. Niech ta usługa wykona wszystkie funkcje potrzebne do Twojej aplikacji. Wykonuj czynności powiązane z tą usługą, aby umożliwić użytkownikom dostęp do bitów interfejsu użytkownika, których potrzebują do interakcji z Twoją „aplikacją”. I mieć menu Android -> Wyjdź (lub wyloguj się, lub cokolwiek) przycisk, który każe usłudze zakończyć, a następnie zamyka samą aktywność.
To jest, dla wszystkich celów i celów dokładnie to, co chcesz powiedzieć. Wykonano na Androida. Spójrz na Google Talk lub Nawigację w Mapach Google, aby zobaczyć przykłady tego „wyjścia” to możliwa mentalność. Jedyna różnica polega na tym, że naciśnięcie przycisku Wstecz poza aktywność może pozostawić proces UNIX czekający na wypadek, gdyby użytkownik chciał ożywić aplikację. To tak naprawdę nie różni się od nowoczesnego systemu operacyjnego, który buforuje ostatnio używane pliki w pamięci. Po zamknięciu programu Windows najprawdopodobniej potrzebne zasoby są nadal w pamięci i czekają na zastąpienie innymi zasobami, ponieważ są ładowane teraz, gdy nie są już potrzebne. Android jest tym samym.
Naprawdę nie widzę twojego problemu.
źródło
System.exit()
usuwa tylko aktywność ze stosu. JVM jest natychmiast ponownie inicjowany. Zobacz tę odpowiedź .To interesująca i wnikliwa dyskusja z udziałem wielu ekspertów. Wydaje mi się, że ten post powinien być zapętlony z poziomu głównej strony internetowej poświęconej programowaniu systemu Android, ponieważ obraca się wokół jednego z podstawowych projektów systemu operacyjnego Android.
Chciałbym również dodać tutaj moje dwa centy.
Do tej pory byłem pod wrażeniem sposobu, w jaki Android obsługuje zdarzenia związane z cyklem życia, wprowadzając koncepcję podobną do sieci w natywnych aplikacjach.
Powiedziawszy, że nadal uważam, że powinien istnieć Quitprzycisk. Dlaczego? ... nie dla mnie, Teda ani żadnego z guru technologii tutaj, ale wyłącznie w celu zaspokojenia zapotrzebowania użytkownika końcowego.
Chociaż nie jestem wielkim fanem systemu Windows, ale dawno temu wprowadzili koncepcję, do której przyzwyczaja się większość użytkowników końcowych (przycisk X) ... „Chcę zrezygnować z uruchamiania widżetu, gdy„ chcę ”.
To nie znaczy, że ktoś (OS, programista?) Zajmie się tym według własnego uznania ... oznacza po prostu „gdzie jest mój czerwony przycisk X, do którego jestem przyzwyczajony”. Moje działanie powinno być analogiczne do „zakończenia połączenia po naciśnięciu przycisku”, „wyłączenia urządzenia poprzez naciśnięcie przycisku” itd. I tak dalej ... to percepcja. Samo w sobie daje satysfakcję, że moje działanie rzeczywiście osiągnęło swój cel.
Mimo że programista może sfałszować to zachowanie za pomocą podanych tutaj sugestii, postrzeganie nadal pozostaje, tzn. Aplikacja powinna całkowicie przestać działać (teraz) przez niezależne, zaufane i neutralne źródło (OS) na żądanie od użytkownika końcowego.
źródło
Państwo może zamknąć, albo przez naciśnięcie Backprzycisku lub poprzez wywołanie
finish()
w twojejActivity
. Wystarczy zadzwonićfinish()
z,MenuItem
jeśli chcesz jawnie go zabić.Romain nie twierdzi, że nie da się tego zrobić, tylko że jest to bezcelowe - użytkownicy nie muszą przejmować się rezygnacją lub zapisaniem swojej pracy, czy cokolwiek innego, ponieważ sposób działania cyklu życia aplikacji zachęca do pisania inteligentnego oprogramowania, które automatycznie zapisuje i przywraca jego stan bez względu na to, co się stanie.
źródło
Ta debata sprowadza się do odwiecznego pytania, czy programiści wiedzą najlepiej, czy użytkownik wie najlepiej. Profesjonalni projektanci we wszystkich obszarach ludzkich czynników zmagają się z tym każdego dnia.
Ted zauważył, że jedną z najczęściej pobieranych aplikacji na rynku jest „App Killer”. Ludzie dostają trochę dodatkowej serotoniny, kiedy opuszczają aplikacje. Są do tego przyzwyczajeni z komputerem stacjonarnym / laptopem. Utrzymuje szybki ruch. Utrzymuje chłodzenie procesora i włączanie wentylatora. Zużywa mniej energii.
Jeśli weźmiesz pod uwagę, że urządzenie mobilne jest znacznie mniejszym statkiem, możesz szczególnie docenić ich zachętę do „wyrzucania za burtę tego, czego już nie potrzebujesz”. Teraz twórcy Androida przekonali się, że system operacyjny wie najlepiej, a zamknięcie aplikacji jest antyczne. Z całego serca to popieram.
Uważam jednak, że nie powinieneś frustrować użytkownika, nawet jeśli frustracja ta wynika z jego własnej niewiedzy. Z tego powodu dochodzę do wniosku, że posiadanie opcji „Wyjdź” to dobry projekt, nawet jeśli w większości jest to przycisk placebo, który robi jedynie zamknięcie Widoku.
źródło
Ted, to, co próbujesz osiągnąć, może zostać zrobione, być może nie tak, jak teraz o tym myślisz.
Proponuję przeczytać o działaniach i usługach. Przestań używać terminu „aplikacja” i zacznij odnosić się do składników, tj. Działania, usługi. Myślę, że musisz tylko dowiedzieć się więcej o platformie Android; jest to zmiana sposobu myślenia w stosunku do standardowej aplikacji na PC. Fakt, że żaden z twoich postów nie zawiera słowa „Aktywność” (oprócz cytatu z FAQ, tj. Nie twoich słów) mówi mi, że musisz przeczytać więcej.
źródło
Wpis na blogu Kiedy włączyć przycisk wyjścia w aplikacjach na Androida (Wskazówka: Nigdy) wyjaśnia to daleko, znacznie lepiej niż potrafię. Chciałbym, żeby każdy programista Androida już to przeczytał.
Fragmenty:
Śmiało i przeczytaj cały artykuł.
źródło
1: Całkowite zamknięcie aplikacji może być zasadniczo nieobowiązkowe, ale nie jest bezużyteczne. Co jeśli system Windows nie miał opcji wyjścia? System byłby bardzo powolny, ponieważ pamięć była pełna, a system operacyjny musiał zgadywać, z których programów korzystałeś. Nie obchodzi mnie, co mówią Romain Guy, a nawet Larry Page i Sergey Brin - są to niepodważalne fakty: systemy działają wolniej, gdy muszą zabijać zadania, aby odzyskać pamięć, zanim będzie można uruchomić nową aplikację. Po prostu nie możesz mi powiedzieć, że zabicie aplikacji nie zajmuje czasu! Nawet światło z odległych gwiazd potrwać ... Nie jest pewne zastosowanie w pozwalając użytkownikowi w pełni bliskich aplikacji.
2: W przeciwieństwie do podstawowych aplikacji? Co to ma znaczyć? Kiedy skończyłem na razie uruchamiać aplikację, nie wykonuje już żadnej pracy ... Po prostu czeka, aż zabije ją system operacyjny, gdy potrzebna jest jej pamięć.
Podsumowując, istnieje wyraźna różnica między minimalizacją a wyjściem, i żadna szczypta nie trafia dobrze w drugą stronę. Czy zostawiamy śrubokręt w każdej śrubie? Czy klucz w każdych drzwiach? Czy zostawiamy wszystkie nasze urządzenia na wysokości, dopóki nie zadziała wyłącznik i musimy włączyć inne urządzenie? Czy zostawiamy zmywarkę pełną naczyń i za każdym razem wyjmujemy tylko tyle, aby zrobić miejsce dla nowych brudnych naczyń? Czy zostawiamy wszystkie samochody jeżdżące na podjeździe, aż - och, nieważne.
Jeśli użytkownik chce zminimalizować aplikację, najlepiej jest ją zminimalizować. Jeśli użytkownik chce wyjść z aplikacji, najlepiej jest wyjść.
Czy to marszczy brwi? To widok Androida - marszczą brwi. I wielu wielu niezależnych początkujących programistów Androida marszczy brwi.
Ale jeśli chodzi o to, jest dobre i złe kodowanie. Istnieją dobre modele przepływu programów i złe modele przepływu programów.
Pozostawienie programów w pamięci, gdy użytkownik wie, że zostały wykonane, po prostu nie jest dobrym przebiegiem programu. Służy to absolutnie bezcelowi i spowalnia rzeczy podczas uruchamiania nowych aplikacji lub uruchamiania aplikacji, które przydzielają więcej pamięci.
To trochę jak twój samochód: zdarza się, że zostawiasz go w ruchu, np. Zatrzymujesz się na światłach stopu, a może przejeżdżasz przez fast food lub zatrzymujesz się w bankomacie. Ale są też inne sytuacje, w których chcesz to wyłączyć - na przykład, gdy wracasz do pracy, do sklepu spożywczego lub nawet do domu.
Podobnie, jeśli grasz w grę, a telefon dzwoni, tak. Zatrzymaj grę i utrzymuj ją. Ale jeśli użytkownik skończy z grą przez jakiś czas, to z całą pewnością pozwól mu wyjść.
Przycisk wyjścia w niektórych aplikacjach powinien być bardziej widoczny niż inne. Na przykład gry lub programy, w których użytkownik może chcieć całkowicie wyjść, powinny mieć oczywiste wyjście. Inne programy, na przykład programy poczty e-mail, w których wyjście jest mało prawdopodobne (aby mógł nadal sprawdzać pocztę e-mail) - programy te nie powinny marnować pierwotnej przestrzeni wejściowej ekranu sterowania z opcją wyjścia, ale dla dobrego przebiegu programu, to powinien mieć opcję wyjścia. Co się stanie, jeśli ktoś zdecyduje, że nie chce, aby jego program pocztowy próbował sprawdzić pocztę e-mail, gdy znajduje się w słabym zasięgu, a może podczas rozmowy przez Skype'a? Pozwól im opuścić program pocztowy, jeśli chcą!
Zawieszanie i wychodzenie to dwa ważne zadania, które nie spełniają roli drugiego.
źródło
Myślę, że chodzi o to, że nie ma potrzeby zamykania aplikacji, chyba że masz wadliwe oprogramowanie. Android zamyka aplikację, gdy użytkownik jej nie używa, a urządzenie potrzebuje więcej pamięci. Jeśli masz aplikację, która musi uruchamiać usługę w tle, prawdopodobnie będziesz chciał ją wyłączyć.
Na przykład Google Listen kontynuuje odtwarzanie podcastu, gdy aplikacja nie jest widoczna. Ale zawsze jest przycisk pauzy, aby wyłączyć podcast, gdy użytkownik skończy z nim. Jeśli dobrze pamiętam, Słuchaj, nawet wstawia skrót na pasku powiadomień, dzięki czemu zawsze możesz szybko przejść do przycisku pauzy. Innym przykładem jest aplikacja, na przykład aplikacja Twittera, która stale odpytuje usługę w Internecie. Tego rodzaju aplikacje powinny naprawdę pozwolić użytkownikowi wybrać, jak często odpytywać serwer, a nawet czy odpytywać w wątku w tle.
Jeśli potrzebujesz kodu działającego przy wyjściu, możesz zastąpić odpowiednio onPause (), onStop () lub onDestroy (). http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
źródło
Service
dalej, aby kontynuować ciągłą pracę w tle, na przykład odbieranie wypychanych danych lub cokolwiek innego. Google Talk nie przestaje działać, gdy używasz innej aplikacji. To samo z odtwarzaczem muzyki. Spójrz na inne aplikacje i jak działają.Jeśli nie jesteś w stanie pojąć, jak utrwalić dane / połączenia (a tym samym swoją „aplikację”), nie będziesz w stanie zrobić tego, co „potrzebujesz”, aby zrobić z Androidem.
Ci, którzy pobierają te urocze małe App Killers, zwykle stwierdzają, że nie pomagają w pracy na baterii ani w zużyciu pamięci, ale utrudniają systemowi wydajne zarządzanie pamięcią ...
http://android-developers.blogspot.com/2010/04/multitasking-android-way.html
źródło
Rozważę przeczytanie „Rozwoju aplikacji bezprzewodowych dla Androida” opublikowanego przez Addison-Wesley. Właśnie kończę i jest to BARDZO dokładne.
Wygląda na to, że masz pewne podstawowe nieporozumienia dotyczące platformy Android. Ja również byłem trochę sfrustrowany cyklem życia aplikacji na Androida, ale po lepszym zrozumieniu zacząłem naprawdę podobać się temu podejściu. Ta książka odpowie na wszystkie twoje pytania i wiele więcej. To naprawdę najlepszy zasób, jaki znalazłem dla nowych programistów Androida.
Myślę też, że musisz puścić port liniowy dla istniejącej aplikacji. Aby przenieść aplikację na platformę Android, niektóre elementy aplikacji zmienią się. Zastosowany cykl życia aplikacji jest konieczny, ponieważ urządzenia mobilne mają bardzo ograniczone zasoby w stosunku do systemów stacjonarnych i umożliwiają urządzeniom z Androidem uruchamianie kilku aplikacji w uporządkowany i świadomy sposób. Przeanalizuj nieco platformę i myślę, że zdasz sobie sprawę, że to, co chcesz zrobić, jest całkowicie wykonalne. Powodzenia.
Nawiasem mówiąc, nie jestem w żaden sposób związany z Addison-Wesley ani żadną osobą lub organizacją związaną z tą książką. Po ponownym przeczytaniu mojego postu czuję, że wyszedłem na trochę fanowskiego. Po prostu bardzo mi się podobało i uważam to za bardzo pomocne. :)
źródło
Niemal w 99% przypadków aplikacja Android nie musi przejmować własnego cyklu życia. W większości przypadków sprowadza się to do lepszego planowania lub inteligentniejszego projektowania aplikacji. Na przykład raczej zbuduj usługę wewnętrzną (nie eksportowaną) do obsługi pobrań itp. Lub zaprojektuj działania i zadania wokół przepływu pracy użytkownika.
Ale powiedziawszy to, tam gdzie jest wola, istnieje sposób. Android zapewnia - za pośrednictwem klasy android.os.Process - znacznie lepszy interfejs API niż Java do kontrolowania podstawowego procesu. I w przeciwieństwie do Javy, nie traktuje programisty jak kretyna, ukrywając wszystko za prostym wywołaniem java.lang.System.exit ().
Jak więc poprosić aplikację o popełnienie samobójstwa w systemie Android? Sztuczka jest prosta:
Utwórz własną klasę aplikacji na Androida, dziedzicząc po standardowej klasie android.app.Application (pamiętaj, aby zadeklarować ją w pliku AndroidManifest.xml).
Zastąp metodę onCreate () i zapisz identyfikator procesu, który uruchomił aplikację:
Teraz, aby zabić aplikację, podaj metodę kill ():
Teraz, gdy potrzebujesz popełnić samobójstwo, po prostu napisz kontekst aplikacji i wywołaj metodę kill!
Pamiętaj tylko, że ze względu na zasady zarządzania procesami w systemie Android, szczególnie związane z usługami, system Android może po prostu zrestartować usługę (zobacz Nie powinieneś używać funkcji zabijania zadań w systemie Android ).
źródło
Gdy tworzę aplikację na Androida, widzę to w następujący sposób:
Aby to zrobić, potrzebujesz tylko Backprzycisku lub Homeprzycisku telefonu (przez krótkie lub długie naciśnięcie) i paska powiadomień.
Kiedy wychodzę z aplikacji, używam Backprzycisku tylko do momentu, gdy go nie opuszczę lub Homeprzycisku.
Tak myślę, że w ten sposób powstaje większość aplikacji. Ale jeśli potrzebuję sesji lub połączenia, wyjaśniłem to użytkownikowi przyciskiem logowania / wylogowania i powiadomieniem (pasek tytułu lub cokolwiek innego). Jest to raczej inny styl niż aplikacja w stylu „wyjścia”.
Na PC masz pulpit z wieloma GUI, a na Androidzie oczywiście masz wiele zadań, ale wyświetlasz tylko jedną aplikację na raz (nie rozważam tutaj widżetów ^^). A na telefonie komórkowym możesz w każdej chwili otrzymać powiadomienie o czymś ważniejszym niż to, co robisz.
Zatem cała koncepcja aplikacji opiera się na czymś innym, co „wchodzi do aplikacji - praca - wychodzi z aplikacji”.
źródło
Hmmmm ...
Myślę, że po prostu nie widzisz aplikacji na Androida we właściwy sposób. Z łatwością możesz zrobić coś prawie tak, jak chcesz:
Czy działania aplikacji zapisują / przywracają stan, tak jak jest to zalecane w dokumentacji cyklu życia dewelopera.
Jeśli konieczne jest zalogowanie się na etapie przywracania (brak dostępnych danych logowania / sesji), zrób to.
W końcu dodaj przycisk / menu / limit czasu, w którym to przypadku zrobisz to
finish()
bez zapisywania loginu i innych informacji o sesji, co pośrednio zakończy sesję aplikacji: więc jeśli aplikacja zostanie uruchomiona / przeniesiona ponownie, rozpocznie nową sesję.W ten sposób nie obchodzi Cię, czy aplikacja zostanie naprawdę usunięta z pamięci, czy nie.
Jeśli naprawdę chcesz go usunąć z pamięci (to jest zalecane, a przy okazji w jakim celu?), Można go zabić warunkowo na koniec
onDestroy()
zjava.lang.System.exit(0)
(a możerestartPackage(..)
?). Oczywiście rób to tylko w przypadku, gdy chcesz „naprawdę zakończyć aplikację”, ponieważonDestroy()
jest to część normalnego cyklu życia działań, a wcale nie koniec aplikacji.źródło
Ponieważ aplikacja w kontekście Androida to tylko kilka niejasno powiązanych działań, zamknięcie aplikacji nie ma większego sensu. Możesz zakończyć () działanie, a widok poprzedniego działania na stosie działań zostanie narysowany.
źródło
Zgadzam się z Tedem. Rozumiem, że zamknięcie aplikacji nie jest „sposobem na Androida”, ale nie wydaje się, że należy to wykluczyć. Oto trzy powody, dla których możesz chcieć prawdziwego wyjścia z aplikacji (nie tylko działania):
Użytkownik może chcieć mieć kontrolę nad tym, która aplikacja zostanie zabita w przypadku braku pamięci. Jeśli w tle jest uruchomiona ważna aplikacja A, możesz zamknąć aplikację B po jej zakończeniu, aby aplikacja A nie została zabita przez system operacyjny.
Jeśli twoja aplikacja ma wrażliwe dane buforowane w pamięci, możesz chcieć ją zabić, aby wirus / robak / nieuczciwa aplikacja nie mogła się do niej dostać. Wiem, że model bezpieczeństwa ma temu zapobiec, ale na wszelki wypadek ...
Jeśli aplikacja korzysta z zasobów (takich jak sieć, procesor, czujniki itp.), Które mogłyby mieć negatywny wpływ na telefon, wówczas jednym ze sposobów zapewnienia, że zasoby te zostaną zwolnione, jest zamknięcie aplikacji. Rozumiem, że dobrze działające aplikacje powinny zwalniać zasoby, gdy nie są potrzebne. Ale znowu wyjście z aplikacji wydaje się rozsądnym sposobem na zapewnienie tego.
źródło
finish()
do działania strony trzeciej, zanim będzie mógł nacisnąć przycisk wyjścia. W tym czasie działalność strony trzeciej powinna zapisywać wszelkie niezapisane informacje. Nie sądzę, że możesz użyć przełącznika aplikacji, aby powrócić do działania przycisku wyjścia, chyba że działa on w osobnym zadaniu. A jeśli jest to osobne zadanie, jest to osobny proces i dlatego nie zostanie zabity przez przycisk wyjścia.Jądro Linuksa ma funkcję o nazwie Zabójca braku pamięci (jak wspomniano powyżej, zasady można konfigurować na poziomie przestrzeni użytkownika, a jądro nie jest optymalne, ale nie jest niepotrzebne).
I jest intensywnie wykorzystywany przez Androida:
OOM Killer nie jest przeznaczony do przestrzeni użytkownika
Notatki na Androida (OOM Killer Info - gdzie możesz skonfigurować funkcję OOM na Androidzie)
Android Porting na rzeczywistym celu
Niektóre aplikacje przestrzeni użytkownika są dostępne, aby pomóc w tych aplikacjach do zabijania, na przykład:
źródło
Najwyraźniej znalazłeś pożądaną odpowiedź w poleceniu finish (). To nie usunie Twojej aplikacji z pamięci, ale Android zrobi to za każdym razem, gdy potrzebuje zasobów, więc nie ma znaczenia, że nie zrobisz tego wprost.
Dodałbym tylko, że w celu uzyskania pełnego efektu, jaki zazwyczaj miałoby wyjście aplikacji, chciałbyś zresetować stan aplikacji do tego, jaki jest normalnie w momencie pierwszego uruchomienia po uruchomieniu urządzenia, tuż przed do wywoływania zakończenia () we wszystkich twoich działaniach. W ten sposób, jeśli użytkownik ponownie wybierze aplikację, będzie wyglądać na uruchomioną „świeżo”, bez żadnego stanu pozostałego od momentu przed symulowanym „wyjściem”.
Jeśli są jakieś specjalne akcje, które powinny wystąpić tylko przy „wyjściu”, takie jak zapisanie pracy użytkownika lub cokolwiek innego, możesz je wykonać przed częścią ponownej inicjalizacji powyższej procedury.
Takie podejście pozwala osiągnąć cel polegający na wydaniu polecenia „exit” bez naruszania filozofii Androida polegającej na pozostawieniu zarządzania zasobami systemu operacyjnego, w tym zamykania aplikacji, w ręce systemu operacyjnego.
Osobiście nie użyłbym tego podejścia, ponieważ użytkownicy Androida oczekują, że aplikacja zachowa ciągłość, gdy ją odwiedzą, a więc nie są przyzwyczajeni do sposobu „wychodzenia” z aplikacji. Zamiast tego wspierałbym funkcję „wyczyść”, którą użytkownik może wywołać, aby zresetować aplikację do domyślnego stanu początkowego, bez konieczności „pozostawiania” jej w tym procesie.
Jedynym wyjątkiem jest sytuacja, gdy użytkownik wciśnie przycisk Wstecz wystarczającą liczbę razy, aby spowodować zamknięcie aplikacji. W takiej sytuacji użytkownik nie oczekuje, że stan zostanie zapisany (a jeśli w aplikacji występuje niezapisany stan, to jako programista powinien mieć kod obsługujący przycisk Wstecz, który wykrywa niezapisane dane, oraz monituje użytkownika o zapisanie go w SharedPreferences lub w pliku lub na innym nieulotnym nośniku).
Odnośnie system.exit (0):
Jeśli zdecydujesz się użyć system.exit (0), aby zamknąć aplikację z grubiańską ostatecznością (np. W wyniku ostatecznego naciśnięcia przycisku Wstecz), to ostrzegłbym cię, że chociaż dla mnie to „działa”, a w niektórych przypadki to jedyny sposób, w jaki udało mi się zamknąć aplikację bez śladu, jest jedna drobna usterka występująca w Jelly Bean, gdy używasz tego podejścia.
W szczególności, jeśli użyjesz listy Ostatnie aplikacje, aby otworzyć aplikację, a następnie użyjesz przycisku Wstecz, aby zamknąć aplikację (z tym zamknięciem zaimplementowanym przez system.exit (0)), lista Najnowsze aplikacje będzie ponownie widoczna, ponieważ będzie nigdy nie były zamknięte. Jeśli następnie dotknij wpisu Twojej aplikacji w tym liście, aby go uruchomić po raz drugi z tego samego, już otwarte, ostatnie listy Apps, nie będzie żadnej reakcji.
Podejrzewam, że przyczyną tego jest to, że lista ostatnio używanych aplikacji zawiera odniesienie do Twojej aplikacji, która przestała działać z powodu zamknięcia aplikacji za pomocą system.exit (0). Bardziej cywilizowane zamknięcie Twojej aplikacji za pomocą metody finish () mogło poinformować system operacyjny w sposób, który pozwoliłby mu odświeżyć listę ostatnich aplikacji, ale system.exit (0) najwyraźniej tego nie robi.
Sam w sobie nie jest to duży problem, ponieważ bardzo niewiele osób otworzy aplikację z ostatnich aplikacji, a następnie ją zamknie, a następnie natychmiast ponownie otworzy z tej samej listy ostatnich aplikacji. A jeśli stukną przycisk Początek, a następnie ponownie otworzą listę Najnowsze aplikacje, pozycja Twojej aplikacji będzie tam i będzie w pełni funkcjonalna. Ale myślę, że pokazuje, że użycie system.exit (0) może zakłócać prawidłową komunikację między twoją aplikacją a systemem operacyjnym, a to sugeruje, że mogą istnieć inne, poważniejsze, być może subtelne, konsekwencje zastosowania tego podejścia.
źródło
Mam nadzieję, że z czasem wszystko się zmieni. Użytkownik powinien mieć możliwość zabicia aplikacji lub procesu, jeśli proces aplikacji jest poprawnie piaskownicą systemu operacyjnego. Istnieje pogląd, że aplikacje powinny być pisane idealnie, w przeciwnym razie użytkownik będzie korzystał tylko z aplikacji zgodnych ze wszystkimi zaleceniami SDK. Myślę, że to duże zamówienie.
źródło
Istnieje (stosunkowo) prosta konstrukcja, która pozwoli ci obejść zagadkę „wyjścia”. Spraw, aby Twoja aplikacja miała stan „podstawowy” (działanie), który jest tylko pustym ekranem. Przy pierwszym utworzeniu działania możesz uruchomić inne działanie, w którym znajduje się główna funkcjonalność aplikacji. „Wyjścia” można następnie dokonać, kończąc () drugie działanie i wracając do podstawy pustego ekranu. System operacyjny może przechowywać ten pusty ekran w pamięci tak długo, jak chce ...
W gruncie rzeczy, ponieważ nie możesz wyjść z systemu operacyjnego, po prostu przekształcasz się we własną stworzoną nicość.
źródło
Bez funkcji wyjścia dla programisty aplikacji w celu zabicia własnej aplikacji jest to bardzo zły projekt.
Moja aplikacja musi pozwalać użytkownikowi dynamicznie zmieniać dane dynamicznie podczas działania, a użytkownik musi zrestartować moją aplikację, aby uzyskać efekt zmiany, ale Android sam nie zezwolił na ponowne uruchomienie aplikacji. System operacyjny Android ma bardzo zły cykl życia aplikacji.
źródło
Aby zamknąć aplikację w dowolnym momencie, użyj
FLAG_ACTIVITY_CLEAR_TOP
flagi w polu Cel, a następniesystem.exit();
Lub istnieje podobny sposób, ale bez,
system.exit()
gdy chcesz wyjść, wywołaj tę metodę:HomeActivity.onCreate()
Dodaj swój kodBędzie to działać bez przerywania cyklu życia Androida.
źródło
Przede wszystkim nigdy nigdy nie używaj System.exit (0). To tak, jakby ktoś spał i uderzył go w głowę!
Po drugie: mam do czynienia z tym problemem. Przed udostępnieniem mojego rozwiązania chcę podzielić się swoimi przemyśleniami.
Myślę, że „przycisk wyjścia” jest głupi. Naprawdę naprawdę bardzo głupio. I myślę, że użytkownicy (konsumenci), którzy proszą o przycisk wyjścia z twojej aplikacji, są również głupi. Nie rozumieją, jak działa system operacyjny i jak zarządza zasobami (i robi to świetną robotę).
Myślę, że jeśli napiszesz dobry kawałek kodu, który robi właściwe rzeczy (aktualizacje, zapisuje i wypycha) we właściwym momencie i warunkach oraz przy użyciu właściwych rzeczy (usługa i odbiornik) będzie działał całkiem dobrze i nikt nie będzie narzekał .
Aby to zrobić, musisz przestudiować i dowiedzieć się, jak działa system Android. W każdym razie jest to moje rozwiązanie, aby zapewnić użytkownikom „przycisk wyjścia”.
Utworzyłem menu opcji zawsze widoczne w każdej aktywności (mam super aktywność, która to robi).
Gdy użytkownik kliknie ten przycisk, dzieje się tak:
Zapisuję więc w SharedPreferences, że chcę zabić moją aplikację i zaczynam zamiar. Proszę spojrzeć na te flagi; te wyczyszczą wszystkie moje backstacki nazywając moją Aktywnością DashBoard, która jest moją aktywnością „domową”.
Tak więc w działaniu Dashboard uruchomiłem tę metodę w polu onResume:
I będzie działać całkiem dobrze.
Jedyną rzeczą, której nie rozumiem, dlaczego tak się dzieje, jest to, że kiedy wykonuję ostatnie zakończenie (i sprawdziłem: śledzi cały prawidłowy przepływ onPause → onStop → onDestroy) aplikacja wciąż wykonuje ostatnią aktywność (ale jest puste).
Wygląda na to, że najnowsza intencja (która uruchomiła DashboardActivity) jest nadal w systemie.
Muszę kopać więcej, aby je również usunąć.
źródło
Cykl życia aplikacji na Androida jest przeznaczony dla użytkowników telefonów komórkowych, a nie użytkowników komputerów.
Cykl życia aplikacji to brutalnie uproszczony paradygmat wymagany do przekształcenia serwera Linux w urządzenie konsumenckie.
Android to Java nad Linuksem, prawdziwy wieloplatformowy system operacyjny serwera. Tak rozprzestrzenił się tak szybko. Cykl życia aplikacji obejmuje rzeczywistą rzeczywistość systemu operacyjnego.
Dla użytkowników mobilnych aplikacje są właśnie zainstalowane lub nie. Nie ma koncepcji biegania ani wychodzenia. W rzeczywistości procesy aplikacji mają działać, dopóki system operacyjny nie zwolni ich ze względu na posiadane zasoby.
Ponieważ jest to przepełnienie stosu, każdy, kto to czyta, jest użytkownikiem komputera i musi wyłączyć 90% swojej wiedzy, aby zrozumieć cykl życia aplikacji mobilnej.
źródło
Przeczytanie tego pytania i odpowiedzi zajęło mi więcej czasu niż wdrożenie częściowo poprawnego cyklu życia aplikacji na Androida.
Jest to aplikacja GPS, która wyszukuje punkty i wysyła aktualną lokalizację do serwisu internetowego co kilka sekund za pomocą wątku ... To może być odpytywanie co 5 minut w przypadku Teda o aktualizację, a następnie onStop może po prostu rozpocząć aktualizację Ted był tak zadowolony martwisz się, czy ktoś został znaleziony (asynchroniczny Ted, nie koduj jak programista Windows, albo twoje programy będą działać jak programy Windows ... eww, to nie jest takie trudne).
Zrobiłem trochę kodu początkowego w onCreate, aby skonfigurować rzeczy na cały okres aktywności, w tym
checkUpdate.start();
:...
Ten kod może być całkowicie niepoprawny, ale działa. To jedna z moich pierwszych aplikacji na Androida.
Voilà, aplikacja, która nie zużywa procesora, gdy jest w tle, ale jest natychmiast gotowa do ponownego otwarcia, ponieważ jest w pamięci RAM (chociaż nie trzyma pamięci RAM, jak w cyklu życia Androida) ... aplikacja jest zawsze gotowa, to telefon chłopaki / dziewczęta. Jeśli aplikacja ma zużywać całą pamięć RAM i nie może zostać zamknięta przez system operacyjny, może przestać dzwonić = P Dlatego system operacyjny musi mieć możliwość zamknięcia aplikacji, gdy jest w tle (jeśli aplikacja nie jest uruchomiona świnia zasobów nie zostanie zamknięta BTW), więc po prostu napiszmy lepsze aplikacje.
źródło
Za każdym razem, gdy przechodzisz do następnej strony przez zamiar, użyj:
Przykład:
Aby żadna aktywność nie była uruchomiona w tle, a gdy chcesz wyjść z aplikacji, użyj:
To wyjście działało dla mnie jak urok :)
źródło
W każdym razie, jeśli chcesz zakończyć aplikację, zawsze możesz zadzwonić
System.exit(0);
.źródło
System.exit()
NIE zabija Twojej aplikacji, jeśli masz więcej niż jedno działanie na stosie. Korzystający z niego programista Androida nie zrozumiał podstawowego cyklu życia aplikacji na Androida. Przeczytaj tę odpowiedź .System.exit(0);
stackoverflow.com/questions/2033914/…Jeśli masz 10,20 .. uruchomionych wielu działań i chcesz je wszystkie zakończyć i wyjść z systemu.
Utwórz tablicę statyczną w
application class
lubconstants class.
Stałe
MainActivity Dodaj bieżące odwołanie do aktywności w tej tablicy
activity = MainActivity.this; Constants.activities.add(activity);
źródło