AsyncTask gibt Fehlermeldung "Can't create handler inside thread that has not called Looper.prepare()"

  • Antworten:2
  • Bentwortet
Philip M.
  • Forum-Beiträge: 90

29.11.2011, 11:21:27 via Website

Guten Morgen,
ich habe folgendes Problem. ich habe mir einen AsyncTask erstellt um XML-Daten asynchron zu laden um dem ewigen ruckeln meiner App vor zu beugen. Mein AsyncTask sieht wie folgt aus:

1import java.util.ArrayList;
2
3import de.micpool.orderdrinks.security.DataPoll;
4import android.os.AsyncTask;
5import android.os.Looper;
6
7public class AsyncXMLLoader extends AsyncTask<String, Void, Void> {
8
9 private XMLLoaderAdapter loader = null;
10
11
12 public static AsyncXMLLoader getInstance(XMLLoaderAdapter loader) {
13 return new AsyncXMLLoader(loader);
14 }
15
16
17 private AsyncXMLLoader(XMLLoaderAdapter loader) {
18 this.loader = loader;
19 }
20
21
22 @Override
23 protected Void doInBackground(String... params) {
24 if(this.loader == null)
25 return null;
26
27 loader.loadXMLData(params);
28 return null;
29 }
30}

Aufgerufen wird das ganze dann wie folgt mit einem XMLLoaderAdapter als InnerClass welches ein von mir selbst geschriebenes Interface ist welches nur die Methode "loadXMLData(String... params)" enthält.

1AsyncXMLLoader.getInstance(new XMLLoaderAdapter() {
2
3 @Override
4 public Object loadXMLData(String... params) {
5 ArrayList<String> ls = DataPoll.getInstance().getPLZList(params[0]);
6 ArrayAdapter<String> adapter = new ArrayAdapter<String>(view, android.R.layout.simple_dropdown_item_1line, ls);
7 view.getTextViewPLZ().setAdapter(adapter);
8 view.getTextViewPLZ().showDropDown();
9 return null;
10 }
11
12 }).execute(s.toString());

Bei der Variable "view" handelt es sich um eine Activity und die Methode view.getTextViewPLZ() gibt einen AutoCompleteTextView zurück. Nun bekomme ich dir Fehlermeldung wie ich sie in der Überschrift stehen habe und verstehe nicht wieso, da meines wissens nach der AsnyTask doch extra dafür gemacht wurde Asynchron die UI zu ändern. Wenn ich Looper.prepare() aufrufe bekomme ich zwar keine Fehlermeldung, allerdings passiert auch nichts in meiner UI. =/ Hat vielleicht jemand eine Idee? Ich denke ich habe hier grundsätzlich etwas falsch verstanden oder Irre ich mich?

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

29.11.2011, 11:34:52 via Website

doInBackground darf nicht auf Views der Activity zugreifen, weil die Methode in einem anderen Thread abläuft, als die Oberfläche.

onPreExecute() und onPostExecute() kannst du hingegen gefahrlos für Updates der Gui nehmen.

Siehe hier: http://developer.android.com/reference/android/os/AsyncTask.html (Abschnitt "The 4 steps")
Dort steht welcher Schritt in welchem Thread abläuft.

— geändert am 29.11.2011, 11:35:11

Antworten
Philip M.
  • Forum-Beiträge: 90

29.11.2011, 11:39:09 via Website

Okay, vielen Dank für die Antwort, dann muss ich mein Konzept nochmal überdenken und das Laden aus dem Web und das setzen in die UI voneinander trennen. :-)

//Edit: Wunderbar. Nachdem ich in der doInBackground() die Daten aus dem Web lade und diese zurück gebe, kann ich die daten dann in der onPostExecute() weiter verarbeiten was in diesem Fall das setzen eines Adapters in der UI ist. Damit ist das Problem gelöst. :-)
Habe meinem Interface nun einfach noch die Methode setUI(ArrayList<?> dataList) hinzugefügt, in der ich dann die UI setzen kann.

— geändert am 29.11.2011, 11:50:44

Antworten