Forum: PC-Programmierung Java/Android Zwei Aktivities eine TCP Class


von Bassti (Gast)


Lesenswert?

Hallo,

also mit Objektorientierung hab ich noch so meine Schwierigkeiten.

Folgendes Problem:
Ich hab verschiedene Ansichten = Activities und möchte gern auf all 
diesen Ansichten auf eine TCP Verbindung zurückgreifen und Daten mit 
dieser Austauschen.
Also so ähnlich wie:

1. Ansicht öffnet die TCP Verbindung (Eingabe der IP)
2. Ansicht empfängt Daten und wertet sie aus
3. Ansicht empfängt auch Daten, stellt sie aber anders dar.

Ich hab da ziemlich Schwierigkeiten wie ich mir diese eine Verbindung 
aufteile. Oder hab ich nur die falsche Herangehensweise? Ich könnte ja 
auch alle Elemente unsichtbar machen und die nächsten einblenden, aber 
das klingt ziemlich unsinnig.

Wäre schön wenn mir jemand was dazu sagen könnte.

Grüße

Basti

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Bassti schrieb:
> Oder hab ich nur die falsche Herangehensweise?

Besser wäre es die Daten in einem gemeinsammen Model zu halten:
- Ein Thread liest daten über TCP und schreibt sie ins Model
- 1..n Threads lesen das Model und zeigen es an

von Bassti (Gast)


Lesenswert?

Hm, und wie sieht das nun praktisch gesehen aus?

Ich habe eine Klasse TCPClient, nun möchte ich aber die Instance der 
Klasse allen Activities zukommen lassen, so das diese Funktionen der 
Classe (oder heißen die jetzt Methoden?) aufrufen können.

Oder war das nicht gemeint?

Grüße

BAsti

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Entweder über den Konstruktor oder über einen setter/getter

von Bassti (Gast)


Lesenswert?

Ich weiß was das ist, aber ich hab keine Ahnung wie ichs anstellen soll. 
Langsam gehen mir die Ideen aus... Ich versuch jetzt alles auf eine 
Activity zu bringen...
ich möchte einfach nur asyncron nen Bytestream auslesen und das klappt 
schon nicht... die Beispielklasse die ich gefunden habe ist für Strings 
und wenn ich Bytes übergeben will stimmt irgendwas nicht, weil die 
Funktion angeblich irgendwie für Strings definiert ist...
1
public class connectTask extends AsyncTask<String,String,TCPClient> {
2
     
3
        @Override
4
        protected TCPClient doInBackground(String... message) {
5
 
6
            //we create a TCPClient object and
7
            mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {
8
                
9
                //here the messageReceived method is implemented
10
                public void messageReceived(byte[] message) {
11
                    //this method calls the onProgressUpdate
12
                    publishProgress(message);
13
                }
14
            });
15
            
16
17
            mTcpClient.run();
18
 
19
            return null;
20
        }
21
 
22
        protected void onProgressUpdate(byte[] values) {
23
    
24
        }
25
    }

Wenn ich hier String als Datentyp übergebe ist alles okay, nur das ich 
die eingehenden Daten dann erst von Byte in String und wieder 
zurückwandeln muss, was mir auch nicht gelingt. Sinnvoll wäre hier nur 
eine Byteübergabe...

Vielleicht kann noch jemand helfen...

Danke

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Bassti schrieb:
> Vielleicht kann noch jemand helfen

Vermutlich ja, das hat jetzt aber doch überhaupt nix mehr mit der 
Ursprungsfrage zu tun! Also die Dinger in den Spitzenklammern nennen 
sich Generics, die musst du dann schon passend zu deinen "Wünschen" 
definieren, die API sagt dazu:
1
AsyncTask<Params, Progress, Result>
2
3
The three types used by an asynchronous task are the following:
4
Params, the type of the parameters sent to the task upon execution.
5
Progress, the type of the progress units published during the background computation.
6
Result, the type of the result of the background computation.
So, das heisst, beim ersten kannst du (vermutlich?) String lassen falls 
deine Eingabeparameter Strings sind. Beim zweiten schreibst du dann byte 
hin, onProgressUpdate erlaubt automatisch ein array des zweiten Typs, 
wenn du arrays von bytearrays hast dann eben byte[].
Da du scheinbar nix zurückgibst als Ergebnis (wieso nicht siehe 
vorherige Anmerkung) kannst du dor einfach Void schreiben, also würde 
deine Definition so aussehen:
1
public class connectTask extends AsyncTask<String, byte, Void> {
2
     protected Void doInBackground(URL... urls) {
3
          //we create a TCPClient object and
4
            mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {
5
                
6
                //here the messageReceived method is implemented
7
                public void messageReceived(byte[] message) {
8
                    //this method calls the onProgressUpdate
9
                    publishProgress(message);
10
                }
11
            });
12
           
13
            mTcpClient.run();
14
            return null;
15
     }
16
17
     protected void onProgressUpdate(byte[]... values) {
18
         // tu was damit...
19
     }
20
21
     protected void onPostExecute(Void result) {
22
         //do nothing here...
23
     }
24
}
Wie gesagt, wenn du wirklich im Hintergrund was machen willst wäre es 
vermutlich mit onPostExecute besser, es sei den deine bytes trudeln 
wirklich Stückweise rein und du willst die auch stückweise verarbeiten.

Allgemein: Schau in die API! Da steht alles drin und meist auch ein 
Codeschnipsel, Beispiele aus dem Netz zeigen oft unvollständig nur das 
was gerade so nötig ist.

von experte (Gast)


Lesenswert?

Bassti schrieb:
> Ich hab da ziemlich Schwierigkeiten wie ich mir diese eine Verbindung
> aufteile. Oder hab ich nur die falsche Herangehensweise? Ich könnte ja
> auch alle Elemente unsichtbar machen und die nächsten einblenden, aber
> das klingt ziemlich unsinnig.
Eine Activity, und dort Views einblenden/ausblenden ist die einfachste 
Lösung. Die kann man wählen, wenn man eine ganz kleine App hat.

Sonst nimmt man einen Service:
http://developer.android.com/guide/components/services.html

von Bassti (Gast)


Lesenswert?

Hallo Läubi...

erstmal danke für das Beispiel... habe das jetzt schon so raus bekommen 
und auch angewendet. Wollte das Byte array und die Länge übergeben... 
zwei Werte wollte die Funktion aber auch nicht haben... da hatte ich 
meine erste positive Erfahrung: Einfach ne Klasse mit den zwei 
Datentypen anlegen und übergeben... sehr schön!

Jetzt bin ich schon recht weit Vorgestoßen... auf der Android Seite 
steht, dass man die Async Task nur benutzt, wenn man mal kurz was im 
Hintergrund machen möchte.
Ich prüfe aber die ganze Zeit ob da Daten über TCP kommen... hmm, darum 
erledige ich auch die Auswertung der eingehenden Daten im 
onProgressUpdate und nicht im onPost...

Jedenfalls ist ja der Emulator bekanntermaßen nicht der schnellste, auf 
dem Handy solls angeblich schneller gehen. Nun habe ich noch das 
Problem, wenn zwei Pakete zu knapp hintereinander kommen, gibt es 
Probleme.
Weiß noch nicht genau ob ich dieses Problem wirklich lösen muss, oder ob 
es auf dem Handy nicht mehr existiert (hab noch kein Android Phone zur 
Hand)...
Wahrscheinlich muss ich so ein List-Element Anlegen, wo ich erstmal 
alles reinschreibe und nach und nach Abarbeite...

Aber da muss ich mich nochmal genauer mit beschäftigen. Den Activity 
Austausch habe ich in der Tat erstmal durch das Konzentrieren auf ein 
"Form" gelöst... also es wird eine neue Activity gestartet für die IP, 
aber das Form schließt sich beim Connect drücken und gibt nur die Daten 
an die Hauptactivity zurück. Dort wird dann die eigentliche Verbindung 
probiert. Nicht ganz so wie ichs mir vorgestellt habe... mehr so zurecht 
gefrickelt...
Noch einen Service zu schreiben, ist mir dann doch zu Heavy als Anfänger 
der ne kleine App braucht...

Grüße

Basti

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Bassti schrieb:
> Wollte das Byte array und die Länge übergeben

Arrays tragen die Länge in Java mit sich herum, ist also nicht unbedingt 
nötig.



Bassti schrieb:
> Nun habe ich noch das
> Problem, wenn zwei Pakete zu knapp hintereinander kommen,
> gibt es Probleme
WAS für Probleme?

Bassti schrieb:
> zwei Werte wollte die Funktion aber auch nicht habe

Schau dir die Signatur an und versuch zu verstehen warum... beim 
programmieren kommt man mit try-and-error nicht sehr weit.

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.