Message Handler erzeugen

  • Hallo,
    ich hätte da mal wieder ein Problem:


    Ich versuche immer noch, Messages vom UI-Thread an einen anderen Thread zu senden.


    Momentan habe ich den neuen Thread mit einem Looper und einem Handler versehen.
    Dazu gibt es eine Menge Beispiele im Netz, aber:
    1. Die wenigsten funktionieren wirklich (Absturz)
    2. Der Handler wird immer "innerhalb des Threads erzeugt. Das finde ich erstens unschön und unübersichtlich, zweitens blickt man nicht mehr durch, wenn der Handler bzw. der Thread größer wird ( bei mir der Fall):


    Also wollte ich den Handler als "separate Methode" definieren, also etwa so:

    Leider bekomme ich das so nicht kompiliert. Kann mir jemand sagen, wie es richtig gemacht wird????

  • 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:


    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 :


    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

  • Hallo das mit dem Import habe ich gesagt, weil du von Compiler Problemen gesprochen hast.



    Irgendwie verstehe ich dein Problem nicht.
    Du hast schon einen funktionierenden Code im letzten Thread von mir bekommen.



    In der Run Methode nur einen neuen Handler erstellen mit mHandler = new Handler();
    Reicht nicht, du hast jetzt einen neuern Handler in den du nichts überschreiben kannst.
    Du kannst da nichts Oberrieden.


    Das mit den geschweiften Klammern ist eine Kurzform von einer abgeleiteten Kasse. Alles was in den Klammern steht ist in der abgeleiteten Klasse.
    Du kannst dir auch eine Klasse richtig mit Namen und extends erstellen und die benutzen. Ausführlicher weg.


    Wenn du nicht alles in der Run Methode haben willst warum erstellt du dir nicht einzelne Methoden und rufst die in der Run auf. Alles was du im Run aufrufst läuft im Thread.


    Dein zweites Beispiel wird und kann nie gehen. Deine Bearbeitung Methode ist jetzt eine neue Methode in der Kasse von Thread
    nicht vom Handler.
    Die wird nie aufgerufen. Ist mit Sicherheit auch ausgegraut.



    Ich glaube du solltest dir die Grundlagen von OOP nochmal ansehen.




    Activity

  • Ich glaube, mein Problem ist eher Java.
    Ich tue mich damit echt schwer, ich finde diese Sprache sehr verworren und umständlich.


    Ich bin in der Zwischenzeit schon weiter gekommen, und bin im Prinzip auf die gleiche Idee gekommen, wie in deinem Vorschlag:


    Ich hab's jetzt so:

    Code
    public class ClassComHandler extends Handler
      {
      @Override
      public void handleMessage(Message msg)
        {
        // Nachricht verarbeiten
        Log.i("Test","Message from UI Thread" );
        }
      }


    Also der UI-Thread erzeugt einen TCP-IP Thread, dieser erzeugt den Handler. UI-Thread,
    TCP-Thread und Handler stehen jetzt in einem separaten File.
    Die Aufrufe vom UI-Thread kommen jetzt auch im Handler an.


    Nur habe ich jetzt wieder das gleiche Problem wie vorher nur in Grün:


    Der Handler kann nicht auf Variablen im TCP-Thread zugreifen.


    Wenn ich also im TCP-Thread die Verbindung aufbaue, habe ich ja einen Socket.
    Und wenn der Sendebefehl vom UI-Thread im Handler ankommt, will ich den Befehl über diesen Socket versenden.
    Nur komme da wieder nicht dran.


    Irgendwie drehe ich mich ständig im Kreis.


    Es ist einfach nicht möglich, Daten von einem Thread in den anderen zu bekommen.
    Immer geht irgendwas nicht.


    Hier nochmal alles zusammen:


  • OK, hab's doch hinbekommen.
    War nur etwas umständlich.
    Man kommt vom Handler aus an die Variablen des Threads nur indirerkt über den Looper.


    Looper parentLooper = getLooper();
    ClassComThread parentThread = parentLooper.getThread();
    parentThread.writer .......

  • Zitat

    Ich bin in der Zwischenzeit schon weiter gekommen, und bin im Prinzip auf die gleiche Idee gekommen, wie in deinem Vorschlag:

    Das ist keine Idee, sondern die ausführliche Schreibweise.





    Zitat

    Und wenn der Sendebefehl vom UI-Thread im Handler ankommt, will ich den Befehl über diesen Socket versenden.


    Nur komme da wieder nicht dran.

    Wie so wenn du den Handler als Innere Klasse von Thread macht kommst du an die Kassen Variablen auch aus dem Handler ran.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!