Uruchamiam zdalne operacje pobierania plików audio i odtwarzania plików audio w wątku w tle przy użyciu AsyncTask
. Pasek Cancellable
postępu jest wyświetlany przez czas trwania operacji pobierania.
Chcę anulować / przerwać AsyncTask
przebieg, gdy użytkownik anuluje (decyduje) operację. Jaki jest idealny sposób na załatwienie takiej sprawy?
android
android-asynctask
Samuh
źródło
źródło
while(running)
zwhile(!isCancelled())
jak mówili inni tutaj w komentarzach.Jeśli wykonujesz obliczenia :
isCancelled()
okresowo sprawdzać .Jeśli wykonujesz żądanie HTTP :
HttpGet
lubHttpPost
gdzieś (np. Pole publiczne).cancel
zadzwońrequest.abort()
. Spowoduje toIOException
wrzucenie do twojegodoInBackground
.W moim przypadku miałem klasę łącznika, której użyłem w różnych AsyncTasks. Dla uproszczenia dodałem nową
abortAllRequests
metodę do tej klasy i wywołałem ją bezpośrednio po wywołaniucancel
.źródło
HttpGet.abort()
z wątku w tle lub otrzymasz plikandroid.os.NetworkOnMainThreadException
.cancel(true)
przerywać żądania? Z dokumentacji:If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
HttpURLConnection.disconnect();
cancel(true)
. Użyłem go i działa.Chodzi o to, że wywołanie AsyncTask.cancel () wywołuje tylko funkcję onCancel w zadaniu. Tutaj chcesz obsłużyć żądanie anulowania.
Oto małe zadanie, którego używam do wywołania metody aktualizacji
źródło
running
flagi. AsyncTask ma wewnętrzną flagę, która jest ustawiana, gdy zadanie zostało anulowane. Wymieńwhile (running)
sięwhile (!isCancelled())
. developer.android.com/reference/android/os/… Więc w tym prostym przypadku nie musiszonCancelled()
nadpisywać.Proste: nie używaj pliku
AsyncTask
.AsyncTask
jest przeznaczony do krótkich operacji, które kończą się szybko (kilkadziesiąt sekund) i dlatego nie trzeba ich anulować. „Odtwarzanie plików audio” nie kwalifikuje się. Nie potrzebujesz nawet wątku w tle do zwykłego odtwarzania plików audio.źródło
onPostExecute()
aby sprawdzić, czy powinieneś kontynuować pracę.Jedynym sposobem na to jest sprawdzenie wartości metody isCancelled () i zatrzymanie odtwarzania, gdy zwróci wartość true.
źródło
W ten sposób piszę moje AsyncTask,
kluczowym punktem jest dodanie Thread.sleep (1);
źródło
Nasza globalna zmienna klasy AsyncTask
I akcja KEYCODE_BACK, która przerywa AsyncTask
Mi to pasuje.
źródło
Nie lubię
cancel(true)
niepotrzebnie przerywać moich zadań asynchronicznych, ponieważ mogą one mieć zasoby do zwolnienia, takie jak zamykanie gniazd lub strumieni plików, zapisywanie danych do lokalnej bazy danych itp. Z drugiej strony miałem do czynienia z sytuacjami, w których zadanie async odmawia zakończenia się przez część czasu, na przykład czasami, gdy główne działanie jest zamykane i żądam zakończenia zadania asynchronicznego z wnętrzaonPause()
metody działania. Więc to nie jest kwestia zwykłego dzwonieniarunning = false
. Muszę wybrać rozwiązanie mieszane: oba połączeniarunning = false
, a następnie danie zadaniu asynchronicznego kilka milisekund na zakończenie, a następnie wywołanie albocancel(false)
lubcancel(true)
.Jako skutek uboczny, po
doInBackground()
zakończeniu, czasamionCancelled()
metoda jest wywoływana, a czasamionPostExecute()
. Ale przynajmniej gwarantowane jest zakończenie zadania asynchronicznego.źródło
W odniesieniu do odpowiedzi Yanchenko z 29 kwietnia „10: Użycie podejścia„ while (running) ”jest fajne, gdy kod w ramach„ doInBackground ”musi być wykonywany wiele razy podczas każdego wykonania AsyncTask. Jeśli twój kod pod „doInBackground” ma być wykonany tylko raz na wykonanie AsyncTask, zawinięcie całego kodu pod „doInBackground” w pętli „while (running)” nie zatrzyma działania kodu w tle (wątku w tle), gdy Sam AsyncTask jest anulowany, ponieważ warunek „while (running)” zostanie oceniony tylko wtedy, gdy cały kod wewnątrz pętli while zostanie wykonany przynajmniej raz. Powinieneś więc albo (a.) Rozbić swój kod pod 'doInBackground' na wiele bloków 'while (running)' lub (b.) Wykonać liczne 'isCancelled'https://developer.android.com/reference/android/os/AsyncTask.html .
Dla opcji (a.) Można więc zmodyfikować odpowiedź Janczenki w następujący sposób:
Dla opcji (b.) Twój kod w 'doInBackground' będzie wyglądał mniej więcej tak:
źródło