Nochmal die Frage etwas genauer beschrieben:
Ich möchte einen TCP/IP Client schreiben.
Alle Beispiele, die ich im Netz finde, funktionieren nicht, sind extrem kompliziert und nicht nachvollziehbar,
Wenn es ein einfaches Beispiel gibt, dann funktioniert es IMMER nach folgendem Schema:
1. Main-Activity erzeugt einen Thread und übergibt das zu sendende Kommando im Konstruktor des Threads.
2. Der Thread wird gestartet,
3. der Thread baut eine Verbindung zum Server auf, sendet das im Konstruktor übergebene Kommando, schließt die Verbindung und beendet sich sofort wieder.
Mit anderen Worten :
1. Ich kann immer nur EIN EINZIGES KOMMANDO an den Server senden, nämlich das, was im Konstruktor des Threads übergeben wurde.
2. Für jedes Kommando, was ich senden möchte, wird eine TCP/IP Verbindung auf-und abgebaut .
Was ich jetzt möchte ist folgendes:
Ich möchte die Verbindung halten.
Ich möchte im Thread Konstruktor NUR die Verbindungsdaten übergeben ( Ip-Adresse des Servers, Port)
Ich möchte, das die Run-Methode des Threads NICHT als Sequenz läuft ( Verbinden, Senden; Verbindung trennen, Thread-Ende !)
Ich möchte, das die Run Methode des Threads in einer Schleife läuft, die erst dann beendet wird, wenn ein "Disconnect" Befehl vom UI-Thread gesendet wird.
Und ich möchte vom UI-Thread aus jederzeit und nacheinander Kommandos an den Thread senden, die dieser dann an den Server weitersendet und die Antwort an den UI-Thread zurückgibt.
Und das bekomme ich nicht hin.
Es ist aber kein Kompilierproblem, kein Absturz oder so, sondern eher ein Verständnisproblem, wie man das im Code formuliert.
Meine erste Idee war:
Ich verpasse dem TCP-Client Thread einfach eine neue Methode:
thread.SendData( String Data )
Das habe ich nicht hinbekommen, ich glaube, das es daran liegt, das man einem eigenen Thread, der von einer Android-Thread Klasse abgeleitet wird, keine Extra Funktionen verpassen kann. Man kann nur die vorhandenen überschreiben ( Was man z.B. mit der Run-Methode macht )
Meine zweite Idee war:
Man verpasst dem Thread eine Message-Queue und sendet einfach Messages vom UI-Thread an den TCP-Thread.
Der Empfänger einer Message ist dann ein Handler.
In den Beispielen im Netz steht immer folgendes:
1. Looper hinzufügen
2. Handler definieren/erzeugen
3. Handler mit dem Loopper verbinden.
Also so:
class MyThread extends Thread
{
public Handler mHandler;
@Override
public void run()
{
Looper.prepare();
mHandler = new Handler()
{
public void handleMessage(Message msg)
{
// Nachricht verarbeiten
}
};
Looper.loop();
}
}
Alles anzeigen
Was mir daran nicht gefällt ist die "eingeschobene" Definition des Handlers.
Wenn man so programmiert, hat man hinterher den kompletten Code einer Applikation in einer Funktion stehen und das finde ich Mist.
Wie bekomme ich den Handler "aus der Run-Methode raus"?
Ich möchte es so haben :
class MyThread extends Thread
{
public Handler mHandler;
@Override
public void run()
{
Looper.prepare();
mHandler = new Handler();
Looper.loop();
}
public void handleMessage(Message msg)
{
// Nachricht verarbeiten
}
}
Alles anzeigen
So geht es aber nicht.
Der Code lässt sich kompilieren.
An den Imports kann es also nicht liegen.
Nur : Wenn ich im UI-Thread etwas sende, kommt es im Handler des TCP-Threads nicht an.
Mir ist auch nicht klar, wie ich beim Erzeugen des Handlers mit new Handler die Verbindung mit meinem Handler herstellen muss.
Und genau das ist die eigentliche Frage