Von zweitem Thread aus auf ListView zugreifen

  • Antworten:16
Ytex
  • Forum-Beiträge: 6

08.03.2013, 20:48:21 via Website

Hallo zusammen,

ich habe ein mächtiges Problem.
Auf meiner Hauptoberfläche habe ein ListView angebracht.
Von meinem Main Activity aus kann ich darauf zugreifen, dh. die Einträge setzen.
Nun erhalte ich die Werte, welche angezeigt werden sollen, von einem zweiten Thread. Dieser wirft einen Fehler, der besagt, dass nur der Thread, der das ListView erstellt hat, auch Zugriff darauf bekommt.
Wie kann ich von meinem 2. Thread aus nun die Einträge aktualisieren?

— geändert am 08.03.2013, 20:51:45

Antworten
Timo D.
  • Forum-Beiträge: 182

08.03.2013, 20:54:24 via Website

Viell. auf die ListView über eine Variable zugreifen. Oder findViewById nutzen. Wenn du damit arbeiten willst, musst du runOnUIThread nutzen.

— geändert am 08.03.2013, 20:55:08

Sichern Sie Ihr Smartphone gegen Diebstahl und erhöhen Sie die Chance, es wiederzufinden. Jetzt neu: Guardian - Anti-Diebstahl Guardian - Anti-Diebstahl Pro https://play.google.com/store/apps/details?id=de.tapps.guardian.pro Guardian - Anti-Diebstahl Trial https://play.google.com/store/apps/details?id=de.tapps.guardian.free

Antworten
Ytex
  • Forum-Beiträge: 6

08.03.2013, 21:04:22 via Website

findViewById wirft den Fehler. Wie funktioniert dieses runOnUIThread? Ich habe keine leicht verständlichen Beispiele gefunden. Leider benutze ich Java noch nicht sehr lange. Sonst würde ich die langen Codes in den Foren wohl schneller begreifen ...

Antworten
Timo D.
  • Forum-Beiträge: 182

08.03.2013, 21:12:09 via Website

Ich habe gerade gesehen, dass man so Zugriff auf die ListView erhält:
1ListView list = getListView();
Es kann Probleme geben, je nachdem, von wo du den Aufruf startest.
Und zum RunOnUIThread:
1runOnUiThread(new Runnable() {
2 public void run() {
3 // UI Action
4 }
5 });
So sieht der aus.

Sichern Sie Ihr Smartphone gegen Diebstahl und erhöhen Sie die Chance, es wiederzufinden. Jetzt neu: Guardian - Anti-Diebstahl Guardian - Anti-Diebstahl Pro https://play.google.com/store/apps/details?id=de.tapps.guardian.pro Guardian - Anti-Diebstahl Trial https://play.google.com/store/apps/details?id=de.tapps.guardian.free

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

08.03.2013, 22:09:56 via Website

Probier mal
1public class ListViewTest extends Activity {
2
3volatile ListView list;
4
5public void onCreate(Bundle savedInstanceState) {
6
7 super.onCreate(savedInstanceState);
8 setContentView(R.layout.main);
9list= (ListView)findElementById(R.id.List1);
10
11}
12
13//Das machst du in deinem Hauptthread

In deinem neuen Thread nutzt du dann einfach die Variable list.
Bin mir nicht sicher, ob es funktioniert.
Volatile funktioniert ähnlich wie synchronized.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Ytex
  • Forum-Beiträge: 6

08.03.2013, 22:18:55 via Website

@Pascal: Klappt leider nicht. Sagt mir wieder man können nur vom Ersteller-Thread auf das ListView zugreifen.
@Timo: Diesen Code zum RunOnUIThread habe ich auch gefunden. Leider wird mir daraus nicht klar, wie ich diesen anwenden muss?

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

08.03.2013, 22:22:12 via Website

Das dachte ich mir, Steuerelemente kann man nicht in einen Thread syncronisieren.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Timo D.
  • Forum-Beiträge: 182

08.03.2013, 22:31:40 via Website

Ich verwende den Code z.B. in einer AsyncTask Klasse. Dort habe ich einen Network Thread. Und um von dort auf die GUI zuzugreifen und diese zu ändern, verwende ich den oben genannten Code. Den Kommentar musst du dann durch ListView l = getListView() ersetzen. Ich weiß ja nicht, wo der Zugriff genau stattfinden soll. Ob in einer inneren Klasse oder sonst wo. Da spielt eventuell auch die Sichtbarkeit und Vererbung eine Rolle.

Sichern Sie Ihr Smartphone gegen Diebstahl und erhöhen Sie die Chance, es wiederzufinden. Jetzt neu: Guardian - Anti-Diebstahl Guardian - Anti-Diebstahl Pro https://play.google.com/store/apps/details?id=de.tapps.guardian.pro Guardian - Anti-Diebstahl Trial https://play.google.com/store/apps/details?id=de.tapps.guardian.free

Antworten
Ytex
  • Forum-Beiträge: 6

08.03.2013, 22:42:31 via Website

Haupt-Activity (HauptAktivitaet) :
1//Methode, die das ListView aktualisieren soll:
2ListView lstAusgabe = (ListView) findViewById(R.id.lstAusgabe);
3public void zeigeNachrichten(){
4 try{
5 ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, netzwerker.getPosteingang());
6 lstAusgabe.setAdapter(adapter);
7 }catch(Exception ex){
8 Log.i("MeinTag", ex.getMessage());
9 }
10 }

Innere Klasse (NetWorker) , die das ListView aktualisieren möchte:

1public class NetWorker extends Thread{
2 private HauptAktivitaet ha = null;
3 private List<String> Posteingang = new ArrayList<String>();
4 public NetWorker(HauptAktivitaet ha){
5 this.ha = ha;
6 }
7 public void nachrichtKommtRein(String sText){
8 Posteingang.add(sText);
9 ha.zeigeNachrichten(); //Hier wird im MainActivity die Methode ausgelöst, die das ListView aktualisiert
10 }
11 public List<String> getPosteingang(){
12 return Posteingang;
13 }
14}

— geändert am 08.03.2013, 22:44:32

Antworten
impjor
  • Forum-Beiträge: 1.793

08.03.2013, 22:49:56 via App

All das, was du in einem zweiten Thread machst, was aber auf Views zugreift, muss in das innere der runOnUiThread Methode geschrieben.

Grus

Liebe Grüße impjor.

Für ein gutes Miteinander: Unsere Regeln
Apps für jeden Einsatzzweck
Stellt eure App vor!

Antworten
Timo D.
  • Forum-Beiträge: 182

08.03.2013, 22:51:11 via Website

Ist das ein Network-Thread?
Du kannst es auch so machen:
1private class NetworkActivity extends AsyncTask<String, Integer, String> {
2 @Override
3 protected String doInBackground(String... arg0) {
4 new Thread(new Runnable() {
5 public void run() {
6 URL url = null;
7
8 try {
9 url = new URL(
10 "http://url.de");
11 String readLine = null;
12 BufferedReader buffReader = new BufferedReader(
13 new InputStreamReader(url.openStream()));
14 while ((readLine = buffReader.readLine()) != null) {
15 runOnUiThread(new Runnable() {
16 public void run() {
17 // Hier erfolgt der ListView Zugriff
18 }
19 });
20
21 }
22 } catch (MalformedURLException me) {
23 me.printStackTrace();
24 } catch (IOException ioe) {
25 ioe.printStackTrace();
26 }
27
28 }
29 }).start();
30 return null;
31 }
32 }
Asynctasks sind gut dafür, die Netzwerkaktivität in einen Thread auszulagern.

Sichern Sie Ihr Smartphone gegen Diebstahl und erhöhen Sie die Chance, es wiederzufinden. Jetzt neu: Guardian - Anti-Diebstahl Guardian - Anti-Diebstahl Pro https://play.google.com/store/apps/details?id=de.tapps.guardian.pro Guardian - Anti-Diebstahl Trial https://play.google.com/store/apps/details?id=de.tapps.guardian.free

Antworten
Timo D.
  • Forum-Beiträge: 182

08.03.2013, 22:54:30 via Website

Ist aus einem größeren Projekt. Gab sonst Probleme wegen dem Netzwerk Thread. Der muss ja separat laufen.

Sichern Sie Ihr Smartphone gegen Diebstahl und erhöhen Sie die Chance, es wiederzufinden. Jetzt neu: Guardian - Anti-Diebstahl Guardian - Anti-Diebstahl Pro https://play.google.com/store/apps/details?id=de.tapps.guardian.pro Guardian - Anti-Diebstahl Trial https://play.google.com/store/apps/details?id=de.tapps.guardian.free

Antworten
Ytex
  • Forum-Beiträge: 6

08.03.2013, 22:56:55 via Website

Dann habe ich das so verstanden, dass meine NetWorker-Klasse, die später auf das ListView zugreift, von AsyncTask erben muss?

Antworten
Timo D.
  • Forum-Beiträge: 182

08.03.2013, 23:00:10 via Website

Ja, da muss ich mich mal schauen, welche Methode das genau brauchte ;)
Genau, so ist das möglich. Netzwerkaktivitäten müssen immer in einem extra Thread laufen. Ich meine, dass das früher nicht so war. Jetzt ist es aber sicher so.

— geändert am 08.03.2013, 23:01:08

Sichern Sie Ihr Smartphone gegen Diebstahl und erhöhen Sie die Chance, es wiederzufinden. Jetzt neu: Guardian - Anti-Diebstahl Guardian - Anti-Diebstahl Pro https://play.google.com/store/apps/details?id=de.tapps.guardian.pro Guardian - Anti-Diebstahl Trial https://play.google.com/store/apps/details?id=de.tapps.guardian.free

Antworten
Ytex
  • Forum-Beiträge: 6

08.03.2013, 23:11:02 via Website

Hm. Scheint auf die schnelle auch nicht zum gewünschten Ergebnis zu führen. Ich werde es für heute sein lassen, vielleicht kommt mir ja noch (oder einem von euch) eine glänzende Idee. Ansonsten gut Nacht :)

EDIT: Prima. Funktioiniert via runOnUiThread :) Man sollte eben nichts mehr spät abends machen ... War grad ne Sache von 5 min ^^ Danke nochmal!

— geändert am 09.03.2013, 09:11:15

Antworten