To bardzo dobre pytanie, jako programista Androida potrzeba czasu, aby w pełni zrozumieć problem. Rzeczywiście, AsyncTask ma dwa główne problemy, które są ze sobą powiązane:
- Są słabo przywiązani do cyklu życia działalności
- Bardzo łatwo tworzą wycieki pamięci.
W aplikacji RoboSpice Motivations ( dostępnej w Google Play ) szczegółowo odpowiadamy na to pytanie. Zapewni dogłębny wgląd w AsyncTasks, Loaders, ich funkcje i wady, a także przedstawi alternatywne rozwiązanie dla żądań sieciowych: RoboSpice. Żądania sieciowe są typowym wymaganiem w systemie Android i są z natury długotrwałymi operacjami. Oto fragment aplikacji:
Cykl życia AsyncTask i Activity
AsyncTasks nie podążają za cyklem życia instancji Activity. Jeśli uruchomisz AsyncTask wewnątrz działania i obrócisz urządzenie, działanie zostanie zniszczone i zostanie utworzone nowe wystąpienie. Ale AsyncTask nie umrze. Będzie żyć, dopóki się nie skończy.
Po zakończeniu AsyncTask nie zaktualizuje interfejsu użytkownika nowego działania. Rzeczywiście aktualizuje poprzednie wystąpienie działania, które nie jest już wyświetlane. Może to prowadzić do wyjątku typu java.lang.IllegalArgumentException: Widok niepołączony z menedżerem okien, jeśli na przykład używasz findViewById do pobierania widoku wewnątrz działania.
Problem z wyciekiem pamięci
Tworzenie AsyncTasks jako klas wewnętrznych działań jest bardzo wygodne. Ponieważ AsyncTask będzie musiał manipulować widokami działania, gdy zadanie jest zakończone lub w toku, użycie wewnętrznej klasy działania wydaje się wygodne: klasy wewnętrzne mogą uzyskać bezpośredni dostęp do dowolnego pola klasy zewnętrznej.
Niemniej jednak oznacza to, że klasa wewnętrzna będzie zawierała niewidoczne odniesienie do swojej instancji klasy zewnętrznej: Activity.
W dłuższej perspektywie powoduje to wyciek pamięci: jeśli AsyncTask trwa długo, utrzymuje aktywność „przy życiu”, podczas gdy Android chciałby się go pozbyć, ponieważ nie można go już wyświetlić. Działania nie można zbierać jako śmieci i jest to centralny mechanizm systemu Android służący do ochrony zasobów na urządzeniu.
To naprawdę bardzo zły pomysł, aby używać AsyncTasks do długotrwałych operacji. Niemniej jednak są one dobre dla krótkotrwałych, takich jak aktualizacja widoku po 1 lub 2 sekundach.
Zachęcam do pobrania aplikacji RoboSpice Motivations , która naprawdę wyjaśnia to szczegółowo i zawiera przykłady i demonstracje różnych sposobów wykonywania niektórych operacji w tle.
doInBackground
funkcja zawiesza ekran, jeśli pasek postępu nie jest używany.