Forum: PC-Programmierung [Android] Multithread zurück zum MainThread (wie?)


von Rene H. (ballibou77)


Lesenswert?

Hallo,

ich tätige in einem zweiten Thread eine HTTPURLConnection. Der URL 
Request steht danach in updateText. Da HTTP Aufgaben ja nur in 
Hintergrund ausgeführt werden dürfen liegt dort auch der Request in 
einem String.

Diesen String benötige ich nun im MainThread, jedoch in einem String. 
Wenn ich den Request in ein TextView mit setText und goString schreibe 
zeigt er mir den Request auch im Layout vom MainThread an. Wenn ich 
diesen aber in einem String weiterverarbeiten will bleibt der String 
leer.

Wie bekomme ich nun den Request des zweiten Threads zurück in den 
MainThread?
1
    public void websiteread(final String weburl) {
2
        new Thread(new Runnable() {
3
4
            public void run() {
5
6
                InputStream is = null;
7
                URL url = null;
8
                BufferedReader reader = null;
9
                StringBuilder stringBuilder;
10
                try {
11
                    url = new URL(weburl);
12
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
13
                    conn.setReadTimeout(10000 /* milliseconds */);
14
                    conn.setConnectTimeout(15000 /* milliseconds */);
15
                    conn.setRequestMethod("GET");
16
                    conn.setDoInput(true);
17
                    // Starts the query
18
                    conn.connect();
19
                    int response = conn.getResponseCode();
20
                    Log.d("DEBUG_TAG", "The response is: " + response);
21
                    is = conn.getInputStream();
22
                    reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
23
                    stringBuilder = new StringBuilder();
24
                    String line = null;
25
                    while ((line = reader.readLine()) != null) {
26
                        stringBuilder.append(line + "\n");
27
                    }
28
                    reader.close();
29
                    final String updateText = stringBuilder.toString();
30
31
                    runOnUiThread(new Runnable() {
32
                        @Override
33
                        public void run() {
34
                            testtest = updateText;
35
                        }
36
                    });
37
38
                    if (updateText != null && !updateText.isEmpty()) {
39
                        Handler uiCallback = new Handler(Looper.getMainLooper());
40
                        uiCallback.post(new Runnable() {
41
                            @Override
42
                            public void run() {
43
44
                                Intent suchergebnisse = new Intent(getApplicationContext(), ergebnisse.class);
45
                                suchergebnisse.putExtra("ergebnisse", updateText);
46
                                startActivity(suchergebnisse);
47
                                finish();
48
49
                            }
50
                        });
51
                    }
52
                } catch (Exception e) {
53
                }
54
            }
55
        }).start();
56
    }

Wenn ich das so mache, also den String mittels Intent putExtra übergebe 
und dann die neue Activity starte habe ich den String in der neuen 
Activity.

Dann öffnet sich jedoch eine neue Activity und die alte schließt sich. 
SO geht es zwar, sieht aber in der App blöd aus wenn ich die Fenster 
immer öffnen und schließen.

Wie kann ich das machen das ich den String in der Haupt Activity wieder 
weiter verarbeiten kann?

Wenn ich den Intent Teil entferne, also so
1
    public void websiteread(final String weburl) {
2
        new Thread(new Runnable() {
3
4
            public void run() {
5
6
                InputStream is = null;
7
                URL url = null;
8
                BufferedReader reader = null;
9
                StringBuilder stringBuilder;
10
                try {
11
                    url = new URL(weburl);
12
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
13
                    conn.setReadTimeout(10000 /* milliseconds */);
14
                    conn.setConnectTimeout(15000 /* milliseconds */);
15
                    conn.setRequestMethod("GET");
16
                    conn.setDoInput(true);
17
                    // Starts the query
18
                    conn.connect();
19
                    int response = conn.getResponseCode();
20
                    Log.d("DEBUG_TAG", "The response is: " + response);
21
                    is = conn.getInputStream();
22
                    reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
23
                    stringBuilder = new StringBuilder();
24
                    String line = null;
25
                    while ((line = reader.readLine()) != null) {
26
                        stringBuilder.append(line + "\n");
27
                    }
28
                    reader.close();
29
                    final String updateText = stringBuilder.toString();
30
31
                    runOnUiThread(new Runnable() {
32
                        @Override
33
                        public void run() {
34
                            testtest = updateText;
35
                        }
36
                    });
37
38
                    if (updateText != null && !updateText.isEmpty()) {
39
                               websiterequest.setText(updateText).toString();
40
                            }
41
                        });
42
                    }
43
                } catch (Exception e) {
44
                }
45
            }
46
        }).start();
47
    }

(websiterequest ist ein TextView) dann setzt er den Request in den 
websiterequest und gibt mir diesen in der Main Activity aus. Das jedoch 
will ich nicht. Ich will den Request ja weiter verarbeiten und dann 
eventuell ausgeben, Spliten wie auch immer.

Versuche ich als anstatt
1
 websiterequest.setText(updateText).toString();

das ganze in einen String zu schreiben
1
websiterequestString = updateText; 
2
Log.d("Teststring: ", websiterequestString);

Dann habe ich zwar im Log den String, also wird der String auch gefüllt, 
jedoch kann ich diesen in der MainClass der App nicht nutzen, also dort 
ist der String weiterhin leer.

Ich hoffe ihr versteht wie ich das meine und könnt mir weiter helfen.

Danke schon einmal.

: Bearbeitet durch User
von java gast (Gast)


Lesenswert?

MyThread mt = new MyThread(42);
new Thread(mt).start();

long o = mt.mt_l;
.
.
.
     class MyThread extends Thread {
         long mt_l;
         MyThread(long mt_l) {
             this.mt_l = mt_l;
         }

         public void run() {
             // do something
              . . .
         }
     }


--> klassen richtig erstellen und benutzen!!!

von Rene H. (ballibou77)


Lesenswert?

Ok. Verstehe den Code nicht so ganz aber werde das schon hinbekommen. 
Hoffe ich.

von java gast (Gast)


Lesenswert?

ich würde in einem seperaten file eine klasse für dein thread anlegen, 
des wollte ich mit dem bsp andeuten

von Hans-Georg L. (h-g-l)


Lesenswert?

java gast schrieb:
> MyThread mt = new MyThread(42);
> new Thread(mt).start();
>
> long o = mt.mt_l;
> .
> .
> .
>      class MyThread extends Thread {
>          long mt_l;
>          MyThread(long mt_l) {
>              this.mt_l = mt_l;
>          }
>
>          public void run() {
>              // do something
>               . . .
>          }
>      }
>
>
> --> klassen richtig erstellen und benutzen!!!

Auszug aus: http://developer.android.com/reference/java/lang/Thread.html

There are two ways to execute code in a new thread. You can either 
subclass Thread and overriding its run() method, or construct a new 
Thread and pass a Runnable to the constructor.

Und weil Java keine Mehrfachvererbung kennt, kannst auch noch das 
Interface Runnable in einer Klasse implementieren.

class MyThreadActivity extends Activity implements Runnable {}


@Rene

Willst du jetzt mehrere Activity oder nicht ?
Willst du nur einen einmaligen HTTP Request ?

Schreib mal genauer was du eigendlich machen willst und wechsle dabei 
nicht immer die Begriffe.

von Rene H. (ballibou77)


Lesenswert?

Also ich will eine Activity haben. Und dann eine Funktion mit der ich 
HTTP Requests machen kann wo dann der Request immer in einem String 
steht.

In PHP wäre das ja z.b. so:

$websiterequest = readwebsite(URL);

In $websiterequest steht nun der Inhalt der Website

So brauche ich das eben in Android.

Also ich frage je nach Request weitere daten per HTTP ab. Diese sollen 
in einem String zum weiter verarbeiten sein.

Wie auch beim uC Programmieren. Ist ein Pin auf low oder high kann ich 
den Status im ganzen Programm nutzen.

Ich will aber nur eine Activity. Also so erklärt. Ich habe ein Textfeld. 
Gebe da eine URL ein. Httpurlcon ruft den request ab und schreib den in 
einen String. Ist der Stribg gefüllt soll die Activity einen Button 
enabled werden. Drückt man nun dadrauf soll der Request String wieder 
per HTTPUrlcon wieder weiter gesendet werden können. Aber alles in einer 
Activity.

von Hans-Georg L. (h-g-l)


Lesenswert?

Da würde ich dir vorschlagen für die HTTP Geschichte einen Service zu 
verwenden. Darin kannst du dann Threads für senden und empfangen 
creieren und den empfangenen Text mit einem Intent über Broadcast an die 
Activity senden. In der Activity musst du Notify Filter setzen damit du 
nur das bekommst was du willst.  Ich muss mal in meine Source Code 
Backups gucken dann kann ich dir vielleicht ein Gerippe dafür hier 
posten. Hab vor Jahren mal etwas ähnliches für einen Kunden gemacht.

von Rene H. (ballibou77)


Lesenswert?

Ja das wäre cool wenn du da noch nen paar Code schnipsel hättest.

von Jim M. (turboj)


Lesenswert?

Rene H. schrieb:
> Ich will aber nur eine Activity. Also so erklärt. Ich habe ein Textfeld.
> Gebe da eine URL ein. Httpurlcon ruft den request ab und schreib den in
> einen String. Ist der Stribg gefüllt soll die Activity einen Button
> enabled werden. Drückt man nun dadrauf soll der Request String wieder
> per HTTPUrlcon wieder weiter gesendet werden können. Aber alles in einer
> Activity.

Dann nimm keinen Thread sondern AsyncTask<>. Dessen onPostExecute() 
Methode läuft im Main Thread und wäre IMO ideal für Deine Aufgabe 
geeignet.

von Hans-Georg L. (h-g-l)


Lesenswert?

Rene H. schrieb:
> Ja das wäre cool wenn du da noch nen paar Code schnipsel hättest.

Du hast eine PN.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.