mam AsyncTask
klasę, którą wykonuję, która pobiera dużą listę danych ze strony internetowej.
W przypadku, gdy użytkownik końcowy ma bardzo powolne lub przerywane połączenie danych w momencie użycia, chciałbym AsyncTask
ustawić limit czasu po pewnym czasie. Moje pierwsze podejście do tego jest takie:
MyDownloader downloader = new MyDownloader();
downloader.execute();
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
@Override
public void run() {
if ( downloader.getStatus() == AsyncTask.Status.RUNNING )
downloader.cancel(true);
}
}, 30000 );
Po uruchomieniu uruchamiany AsyncTask
jest nowy program obsługi, który anuluje działanie AsyncTask
po 30 sekundach, jeśli nadal działa.
Czy to dobre podejście? A może jest coś wbudowanego, AsyncTask
co lepiej nadaje się do tego celu?
java
android
android-asynctask
Jake Wilson
źródło
źródło
Odpowiedzi:
Tak, istnieje AsyncTask.get ()
Zauważ, że wywołanie tego w głównym wątku (AKA. Wątek UI) zablokuje wykonanie, prawdopodobnie będziesz musiał wywołać to w osobnym wątku.
źródło
handler
podejścia, które opisuję w moim pytaniu? Wydaje się o wiele prostsze, ponieważ wątek interfejsu użytkownika nie zawiesza się podczas oczekiwania na uruchomienie programu Handler Runnable ...W przypadku, gdy Twój program do pobierania jest oparty na połączeniu z adresem URL, masz kilka parametrów, które mogą pomóc w zdefiniowaniu limitu czasu bez złożonego kodu:
Jeśli po prostu wprowadzisz ten kod do zadania asynchronicznego, wszystko jest w porządku.
„Read Timeout” służy do testowania złej sieci podczas całego transferu.
„Limit czasu połączenia” jest wywoływany tylko na początku, aby sprawdzić, czy serwer działa, czy nie.
źródło
Użyj klasy CountDownTimer po stronie rozszerzonej klasy AsyncTask w metodzie onPreExecute ():
Główną zaletą jest monitorowanie Async wykonywane wewnętrznie w klasie.
na przykład zmień CountDownTimer (7000, 7000) -> CountDownTimer (7000, 1000) i wywoła onTick () 6 razy przed wywołaniem onFinish (). Jest to dobre, jeśli chcesz dodać monitorowanie.
Dzięki za wszystkie dobre rady, które otrzymałem na tej stronie :-)
źródło
Nie sądzę, by było coś takiego wbudowanego w AsyncTask. Twoje podejście wydaje się być dobre. Po prostu pamiętaj, aby okresowo sprawdzać wartość isCancelled () w metodzie doInBackground AsyncTask, aby zakończyć tę metodę, gdy wątek interfejsu użytkownika anuluje ją.
Jeśli z jakiegoś powodu chcesz uniknąć korzystania z programu obsługi, możesz okresowo sprawdzać System.currentTimeMillis w swoim AsyncTask i kończyć po przekroczeniu limitu czasu, chociaż bardziej podoba mi się twoje rozwiązanie, ponieważ może faktycznie przerwać wątek.
źródło
źródło
Możesz ustawić jeszcze jeden warunek, aby anulowanie było bardziej niezawodne. na przykład,
źródło
Inspirując się pytaniem, napisałem metodę, która wykonuje pewne zadania w tle za pośrednictwem AsyncTask i jeśli przetwarzanie zajmie więcej niż LOADING_TIMEOUT, pojawi się okno dialogowe z ostrzeżeniem, aby ponowić próbę.
źródło