AsyncTask
Die Klasse AsyncTask ermöglicht es, einen Ablauf in den Hintergrund zu stellen.Sie erstellen eine eigene AsyncTask, indem Sie AsyncTask erweitern. Sie erhält dabei drei Generics-Parameter (auch Typ-Parameter genannt), die für
- Eingabeparameter
- Fortschrittsmeldungswerte
- Rückgabewert
import android.os.AsyncTask; public class MeinAsyncTask extends AsyncTaskSie können dann folgende Methoden überschreiben:{ @Override protected Integer doInBackground(String... parameter) { } @Override protected void onProgressUpdate(Integer... progress) { } @Override protected void onPostExecute(Integer result) { } }
- doInBackground
Diese Methode enthält den Code, der im Hintergrund laufen soll. - onPreExecute
Von hier kann die Oberfläche bearbeitet werden, bevor doInBackground aufgerufen wird. - onProgressUpdate
Zwischenaktualisierungen der Oberfläche wie ein Fortschrittsbalken können von hier aktualisiert werden. - onPostExecute
Die Methode wird nach Ablauf von doInBackground aufgerufen und erhält als Parameter den Rückgabewert von doInBackground. Die Methode ist mit dem Oberflächen-Thread synchronisiert. Die Ergebnisse können also in den Oberflächen-Elementen dargestellt werden.
MeinAsyncTask async = new MeinAsyncTask(); String param[] = { "http://www.willemer.de/index.htm"}; async.execute(param);Jedes Objekt einer AsyncTask kann nur einmal per execute aufgerufen werden. Wird eine zweite Ausführung benötigt, muss ein neues Objekt erzeugt werden, ansonsten droht eine Exception.
Rückgabe der Ergebnisse
Häufig möchte man die Ergebnisse der Hintergrundjobs weiterverwenden. Dazu kann man beispielsweise einen Callback hinterlegen, der nach Ende der Aufgabe aufgerufen wird.Als Beispiel dient die selbstdefinierte Klasse HttpAsyncTask, die AsyncTask erweitert. Sie soll über ein selbstdefiniertes Interface HttpAsyncAntwort den Interessenten aufrufen. In diesem Fall ist es die Activity selbst.
public class HttpAsyncTask extends AsyncTaskDie Referenz auf das Antwort-Interface wird dem Konstruktor übergeben, damit das aufzurufende Objekt gespeichert werden kann. Das Interface ist folgendermaßen realisiert:{ private HttpAsyncAntwort httpAntwort = null; public HttpAsyncTask(HttpAsyncAntwort callback) { httpAntwort = callback; } private String antwort = "";
public interface HttpAsyncAntwort { public void eventAntwort(String str); }Der Rückruf wird in der Methode onPostExecute realisiert.
public class HttpAsyncTask extends AsyncTaskDie AsyncTask wird von der MainActivity aus erzeugt und aufgerufen.{ // ... @Override protected String doInBackground(String... parameter) { // ... return antwort; } @Override protected void onPostExecute(String result) { this.httpAntwort.eventAntwort(antwort); result = this.antwort; } }
public class MainActivity extends AppCompatActivity implements HttpAsyncAntwort { TextView tv; // ... HttpAsyncTask asyncTask = new HttpAsyncTask(this); String url = // ... asyncTask.execute(url); // ... @Override public void eventAntwort(String str) { if (tv!=null) { tv.setText(str); } }
Link
HandlerThread
private HandlerThread handlerThread; private Handler handler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handlerThread = new HandlerThread("MeinHandlerThread"); handlerThread.start(); handler = new Handler(handlerThread.getLooper()); } @Override public void onDestroy() { super.onDestroy(); handlerThread.quitSafely(); }Der HandlerThread wird mit den folgenden Zeilen aus dem Haupt-Thread gestartet.
handler.post(new Runnable() { public void run() { // Das geht alles im Hintergrund } });
Auf den UI-Thread zugreifen
Wenn ein Hintergrund-Thread wieder auf die Oberfläche zugreifen will, kann es ein Runnable über die Methode runOnUiThread mit Zugriff auf den UI-Thread starten, der dann auf die Elemente der Activity zugreifen kann.runOnUiThread(new Runnable() { @Override public void run() { textView.setText(antwort); } });
Rückmeldung über Observer
Auf dem Wege eines Observers kann sich eine Activity bei einem Hintergrund-Thread als Interessent für Änderungen anmelden. Auf diesem Weg kann eine Activity auf das Ende eines Tasks reagieren, ohne darauf warten zu müssen.