2010-10-10 9 views
27

Potrzebuję mojej aplikacji na Androida, aby zapisać stan na dysku, gdy jego aktywność zostanie umieszczona w tle lub zabity. Zasugerowano, że uruchamiam wątek, gdy wywoływana jest funkcja onPause() i wykonuję tam wszelkie kosztowne procedury I/O (patrz Saving/loading document state quickly and robustly for image editor).W jaki sposób system Android obsługuje wątki w tle po opuszczeniu działania?

W jakich sytuacjach OS zabije wątek i jak często zdarzają się takie sytuacje?

Zakładam, że będzie to wyglądać w jaki sposób działania są rozwiązywane tam, gdzie system operacyjny może dowolnie decydować o zabiciu wątku, ale w większości przypadków zrobi to tylko wtedy, gdy zasoby są bardzo ograniczone. Byłoby miło znaleźć jakąś szczegółową dokumentację tego.

Od zabawy, z pewnym kodem testowym, wątek w tle uruchomiony w onPause() będzie działać w tle na moim urządzeniu (próbowałem ładować wiele aplikacji i nie mogłem go zabić).

Dla mojej konkretnej aplikacji, piszę edytor bitmap, w którym używam wzorca polecenia i wzorca Memento, aby umożliwić cofanie i ponawianie zmian. Chciałbym, aby użytkownik mógł cofnąć/ponowić zmiany nawet na przykład użytkownik otrzymuje połączenie telefoniczne, a działanie zostaje zabite, gdy zostanie umieszczone w tle. Najlepszym rozwiązaniem, jakie mogę sobie wyobrazić, jest użycie wątku tła do ciągłego zapisywania moich poleceń i obiektów memento na dysk podczas używania aplikacji i do zakończenia zapisywania wszelkich obiektów, które pozostały w wątku tła, jeśli wywołana jest funkcja onPause. W gorszym przypadku, jeśli wątek zostanie zabity, stracę tylko trochę zmian.

Odpowiedz

21

W jakich sytuacjach OS zabije wątek i jak często zdarzają się takie sytuacje?

System operacyjny nie zabije wątku, chyba że zabija proces - Android nie robi nic z wątkami, które sam tworzysz. Jeśli jesteś na pierwszym planie, nie będziesz zabity. Szanse na Android zabicie procesu w ciągu kilku sekund od utraty pierwszego planu (po onPause()) są niewielkie. Dokumentacja dotycząca żywotności procesu - co tam jest - znajduje się pod adresem here.

+1

Aby wyjaśnić, jeśli utworzysz wątek w procesie dołączonym do jakiejś aktywności, wątek ten zostanie zabity, gdy aktywność zostanie zabita (tj. Proces i wątek są połączone)? – memcom

+2

@tifftuff: Działanie nie jest aplikacją. Działanie jest składnikiem aplikacji. Aplikacja może mieć wiele komponentów, w tym wiele działań, usług itp. Kiedy ostatni składnik aplikacji zostanie zniszczony (np. Użytkownik naciśnie BACK z jedynej aktywności w małej aplikacji), proces ten jest przeznaczony do recyklingu lub zakończenie. NIE WYJMUJ GWINTÓW. Jeśli uruchomisz wątek, musisz go zakończyć, ponieważ Android go nie zakończy, z wyjątkiem zakończenia procesu, który może nie wystąpić przez kilka tygodni. – CommonsWare

+0

Dzięki. Czy masz jakieś zalecenia dotyczące tego, czy usługa byłaby bardziej odpowiednia niż wątek do tej pracy w tle? – memcom

1

Zazwyczaj zapisywanie stanu w jest właściwe, jeśli jest szybkie. Nie sądzę, że jest to wyraźnie udokumentowane, gdy proces jest zabijany, ale czasami widzisz go w logcat, gdy uruchamiasz jakieś wymagające aplikacje (powiedzmy, po uruchomieniu Google Earth i przeglądarki).

W systemie Android DevTools dostępna jest również opcja automatycznego niszczenia czynności podczas poruszania się od nich, chociaż prawdopodobnie nie obejmuje to procesu. (DevTools są na emulatorze i na niektórych telefonach zrootowanych).

Myślę, że twoje podejście brzmi rozsądnie - używaj wątku o niskim priorytecie, aby stale aktualizować dane składowania, i nadawaj mu normalny priorytet w trybie onPause, a także ustaw flagę onPause, która nakazuje jej zakończenie po jej zakończeniu.

Oczywiście musisz się upewnić, że nie napotkasz problemów z synchronizacją, jeśli automatycznie uruchomisz funkcję onResume po operacji onPause (tj. Gdy wątek jest nadal zajęty zapisywaniem).

5

Wątek może zostać zabity w dowolnym momencie po zniszczeniu działania lub może nigdy nie zostać zabity. W zależności od tego wątek jest bardzo złą formą - możesz skończyć z na wpół ukończoną operacją lub z nicią, która wisi na zawsze.

Jeśli chcesz wykonać operację w tle, która trwa nawet w przypadku braku aktywności na pierwszym planie, prawie zawsze chcesz uruchomić ją w ramach usługi.Z drugiej strony, usługa ta jest mniej prawdopodobna, abymogła zostać zabita, ale nie ma gwarancji, chyba że użyjesz "startForeground". Spowoduje to wyświetlenie powiadomienia użytkownika, że ​​coś dzieje się w tle, ale z tego, co wiem, jest to jedyny sposób uruchomienia asynchronicznego wątku tła, który gwarantuje, że nie zostanie zabity.

Szczerze mówiąc, właściwą odpowiedzią jest upewnienie się, że nigdy nie ma tymczasowego stanu procesu, którego zapisanie zajmie dużo czasu. Jeśli musisz napisać duży plik, aby odzwierciedlić kilka zmian wprowadzonych przez użytkownika, rozważ utworzenie "dziennika transakcji", za pomocą którego można utworzyć operację składowania możliwą do ponownego uruchomienia. Biorąc pod uwagę to, możesz bezpiecznie uruchomić swoje zapisy w usłudze i wiedzieć, że nawet jeśli zostanie zabity, zostanie automatycznie uruchomiony ponownie, gdy zasoby staną się dostępne.

+0

Wątek zakończy się w ciągu około 5 sekund, gdy czekam, aby potwierdzić, że moje dane zostały zapisane na dysku (około 2 MB wartości). Mój automatyczny program ładujący uwzględni, że wątek może zostać zabity przed zakończeniem, a użytkownik może stracić 30 sekund pracy. Nie uważasz, że uruchomienie usługi w tym celu jest trochę ciężkie? Mógłbym utworzyć dziennik transakcji operacji edycji, ale te muszą być również zapisane na dysku przy wyjściu (gdzie jeszcze mogę go szybko przechować?), A użytkownik może dokonać dużej edycji, a następnie zostać przerwanym. – memcom

+1

Uruchamianie nowej usługi to absolutnie * nie * za waga ciężka. Jest to zalecany sposób wykonywania czynności, na przykład podczas przetwarzania powiadomienia o widgetie, jeśli zajmie to więcej niż sekundę. Usługi zapewniają * dokładnie * to, czego szukasz - system zda sobie sprawę, że ma dobry powód, aby się trzymać i będzie starał się unikać wyprzedzającego zabijania ich, abyś mógł być o wiele bardziej pewny, że dostaniesz 5 sekundy przetwarzania w tle. Wygląda na to, że jesteś już dobrze przygotowany na rzadki przypadek, w którym usługa musi zostać zabita, więc to wszystko, czego potrzebujesz. – beekeeper

Powiązane problemy