Methoden für Thread richtig strukturieren

  • Hallo zusammen,


    ich habe eine Frage zum Thema Threading/Nebenläufigkeit:


    Ausgangssituation:
    Ich habe eine Klasse MyConnection, die


    1. Eine Runable beinhaltet, um den Datenstrom einer Socketverbindung auszuwerten
    2. Eine Methode beinhaltet, die erst diesen Socket aufmacht und dann den Thread für die Runable startet:



    Wenn ich nun in meiner MyAppActivity zB in der onCreate() ein Objekt dieser Klasse erstellen möchte, hängt der Socket ja zunächst mal im Main Thread, was ja werder sinnvoll noch erlaubt ist. Nur: Wie strukturiere ich das besser?


    - Das Öffnen des Sockets mit in die run()-Methode packen (vor die Endlosschleife)?
    - Das Objekt der Klasse MyConnection noch einmal in einer anderen Klasse "kapseln" (Also eine neue Klasse MyWrapper implements runable bekommt eine Methode run(), in der ich das Objekt erzeuge; aus meiner Activity erstelle ich dann ein Objekt von MyWrapper)?
    - ...?


    Vielen Dank schonmal,
    FargoTof

  • Ach ja, die erste Variante funktioniert ja schon dann nicht, wenn MyClass noch irgendeine Methode bekommen soll, in der etwas auf dem Socket geschrieben werden soll... Diese Methode würde das ja nun wiederum im Main-thread machen...?

  • Hi fargotof,


    soll das Programm die ganze Zeit auf der "Socket Verbindung" lauschen ob der Server eine Nachricht schickt oder wird die Verbindung nur kurz zur Datenübermittlung genutzt?


    für eine kurze Verbindung zur Datenübermittlung könntest du die Klasse AsynTask nutzen.


    Zitat

    Wenn ich nun in meiner MyAppActivity zB in der onCreate() ein Objekt dieser Klasse erstellen möchte, hängt der Socket ja zunächst mal im Main Thread, was ja werder sinnvoll noch erlaubt ist.


    Warum denkst du das das nicht erlaubt ist? Du startest doch im Main Thread einen neunen Thread und dieser läuft dann parallel zum Main Thread.
    Es geht ja nur darum das der Main Thread nicht mehr als ca 5 - 8 sec warten muss, da sonst die Anwendung blockiert und der User eine Meldung bekommt.


    Mfg Titus

  • Also, der Socket bleibt dauerhaft auf und wartet auf Botschaften gemäß eines eigenen Protokolls (in der Endlosschleife). Bei jeder Botschaft wird dann irgendetwas durchgeführt, aber das ist ja erstmal nebensächlich.


    Aber solange ich mir aus meiner Activity heraus wie oben beschriebe meine Instanz von Connection baue, wird open() ja eben auch im Main-Thread ausgeführt, was zu einer NetworkOnMainThreadException führt.


    Viele Grüße,
    Fargotof

  • Hallo


    ich habe mir eben nochmal alles durchgelesen und bin zu dem Schluss gekommen, dass meine Frage vllt spezieller klingt, als sie eigentlich ist, mir hapert es ja an dieser Stelle vllt an einem gewissen Grundverständnis.


    Daher möchte ich noch einmal mein Ziel formulieren, ggf. ist ja o.g. Ansatz schon zu falsch und zu verwirrend.. ;)


    Also:


    Ich habe ja meine Klasse Connection. Diese dient dazu, die Socketverbindung aufzubauen, auf dem Socket zu lauschen und ggf. auch über entsprechende Methoden etwas darüber zu schreiben.


    In meiner MyAppActivity erzeuge ich mir dazu also eine Instanz von Connection und rufe dessen Methode open() auf. Der Socket wird geöffnet und anschließend meine Runnable runnable als neuer Thread gestartet, der im Hintergrund in Endlossschleife auf eingehende Infos wartet und diese bei Bedarf weiter verarbeitet.


    Soweit so gut. Das von mir geschilderte Problem, nämlich dass ich einen Socket im MainThread öffnen möchte (nämlich beim aufrufen von open()) ließe sich nun noch umgehen, indem ich den try/catch-Block mit dem Öffnen den Sockets mit in die runnable packe. Dann passiert auch das schon im neuen Thread.


    Was aber nun, wenn ich eine weitere Methode, sagen wir sendString(String s) für meine Klasse Connection definieren möchte, mit der man Strings auf den socket schreiben kann:


    PHP
    public void send(String s){
        	try {
            	output.write(s);
            	output.flush();
        	} catch(IOException ex) {
            	// ...
        	}
    	}


    (output ist der OutputStreamWriter vom Socket)


    Wie kriege ich es hin, dass auch dieses Schreiben in einem anderen Thread ausgeführt wird? Weil rufe ich aus Meiner MyAppActivity zb. myConnection.send("Hallo!"); auf, geschieht das ja im Hauptthread (dem UI-Thread), oder nicht?


    Verwirrte Grüße,
    FargoTof

  • Vielleicht möchtest du die Nachricht erst mal nur in eine Warteschlange (ArrayList o.ä.) eintragen, dann kommt der Aufruf sofort zurück.


    Dann musst du regelmäßig nachschauen, ob was zum senden vorliegt und dann einen Sendeversuch starten. Wenn der Versand erfolgreich war, kannst du den Eintrag aus der Warteschlange entfernen.


    Wenn du mehrere Sende-Threads parallel laufen lassen möchtest (das ist ja das reizvolle bei Threads), dann aufpassen, dass du einen Eintrag nicht mehrfach verschickst. Stichwort [wikipedia]Threadsicherheit[/wikipedia].

  • genau - erstmal mit while (sendeListe.size() > 0) anfangen und zuerst den Eintrag markieren als "Sendeversuch", dann eine kleine Methode zum Senden aufrufen (kann ein eigener Thread sein). Später dann nachschauen, ob das Senden geklappt hat (der Sender kann ja "gesendet" eintragen) und dann löschen.


    Und wenn der Eintrag nach einer gewissen Zeit (gleich mit eintragen) nicht gesendet wurde, kannst du dir was überlegen - entweder längere Zeit warten (bis wieder Netzwerkverbindung besteht) oder den Benutzer informieren.

Jetzt mitmachen!

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