Beiträge von block_

    Es wurde kein Framework genutzt. Der Server, und der Client auch, wurde mit Java(Android) selbst implementiert (Plain Sockets).
    Also die ganze App sieht bisher so aus:
    In der App ist sowohl der Client-Anteil, als auch der Server-Anteil, damit die App unabhängig von externen Server ist (und man in jedem Netzwerk, in das man reinkommt, die App nutzen kann). Kommuniziert wird nur über WLAN, nicht übers Internet. Befinden sich mehrere Geräte im WLAN, kann eines davon einen Server starten mit dem sich die anderen verbinden und Daten austauschen können.


    block_

    Ein Paket mit den Klassen hab ich mir auch schon überlegt, allerdings bin ich mir nich sicher ob das so sinnvoll ist, da es schon jetzt eine Menge Befehle sind. Wenn man das laden dann noch mit Reflection lösen könnte, würde ich mir das nochmal überlegen, aber wie ich das gesehen hab geht das nicht so wirklich.
    Müsste man mal ausporbieren, welche der beiden Methoden praktikabler ist.


    block_

    Also, ich habe eine Client/Server Anwendung geschrieben, die Daten und Befehle (einfache Strings) hin und her schickt. Die Verarbeitung übernimmt dabei ein eigenes Protokoll. Bislang sieht das so aus, das ich Konstanten habe, die die Befehle definieren und eine Methode mit sehr vielen If-Bedingungen, welche die weitere Verarbeitung übernimmt (je nachdem welcher Befehl gesendet wurde).
    Dafür hab ich ein Interface,..

    Code
    public interface Protocol
    {
       public static final String COMMAND_1 = "befehl1";
       //[...]
    
    
       public void process(String input);
    }


    ... welches von zwei Klassen implementiert wird (jeweils ein ServerProtocol und ein ClientProtocol).

    Code
    public class ServerProtocol implements Protocol
    {
       public void procss(String input)
       {
          if(input.equals(Protocol.COMMAND_1)
          {   // tu was
          }
         // [... und viele weitere]
       }
    }


    Das ist jedoch sehr Erweiterungs- und Wartungsunfreundlich wie ich finde. Wie könnte man das anders lösen?


    Mein bisherigen Idee ist folgende:
    Ich habe eine abstrakte Klasse für einen Befehl:


    In dem ServerProtocol gibt es nun eine Map, in der alle möglichen Befehle für die Server-Seite eingefügt werden.


    Aufgerufen wird das dann durch die process(String input) Methode.

    Code
    @Override
        public void processInput(String data)
        {
    	commands.get(data).execute();
        }


    Das ist schon besser als vorher, jedoch auch nicht ganz optimal, da man auch hier wieder suchen muss, wenn man einen Befehl ändern will. Hab da gedacht, man könnte eventuell etwas mit Reflection machen, aber das funktioniert auch nicht, da ich das nicht automatisieren kann, da die Verarbeitung eines Behfels ja immer unterschiedlich ist.


    Also nochmal die Frage, gibt es eine bessere Möglichkeit?


    block_

    antifish
    Zwei Klassen für eine Hilfsmethode halte ich persönlich etwas zu viel.
    Statt der zweiten non-static Klasse kann man doch genauso gut direkt die statische Methode aufrufen. (Warum ist die Tools-Klasse abstract?)


    maalbert


    Und Aufruf in der Activity:

    Code
    Tools.vibrate(this, 1000);


    So mach ich das immer und es funktioniert einwandfrei.


    block_

    Was spricht denn dagegen, die Methode einfach static zu machen?
    So wie Lucas de Vil schon angedeutet hat (nur das der Context noch mitgegeben wird)

    Code
    public static void vibrate(Context context, int length)
    {
        ((Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE)).vibrate(length);
    }


    Diese Methode soll ja nicht den Zustand eines Objektes verändert, daher ist es in deiner Utility-Klasse ganz gut aufgehoben.


    block_

    Um die Dauer von etwas zu berechnen, würde ich nicht ein Date-Objekt nehmen. Das ist, wie du schon gesagt hast sehr ungenau. Nimm stattdessen

    Code
    long start = System.nanoTime();
    /*
    weiterer code
    */
    long end = System.nanoTime()


    Die Differenz von beiden ergibt ein mehr oder weniger genaues Ergebnis (besser als Date ;) )


    Grundsätzlich lässt sich mit Java auch sehr perfomant arbeiten, solange man es richtig macht. Vorher würde ich prüfen ob du auch wirklich alles rausgeholt hast, was irgendwie möglich ist. Wenn du dann immer noch nativen Code einbinden möchtest, solltest du dir das Android NDK mal anschauen. Gibt auch eine Menge Tutorials dazu im Netzt.


    block_

    das wurde nicht nur angeschnitten das ist schon relativ verbreitet, aber leider wie mein vorredner erkannt hat, sehr instabil.


    Meinst du jetzt JavaFX in Kombination mit Android oder JavaFX im Allgemeinen?
    Das JavaFX weit verbreitet ist, ist mir bewusst, wird ja schließlich ab Java SE 7 mit ausgeliefert. Ich meinte die Unterstützung für Android wurde auf der JavaOne angeschnitte. Falls ich mich irre, lass ich mich gerne belehren :) Würde mich freuen genaueres dazu zu lesen, falls es so sein sollte.


    block_

    Also laut Logcat wird eine NPE geworfen und zwar in der onCreateView der Klasse Fragment_Map (Zeile 39). Jedoch passt das nicht zu dem von dir angegebenen Code. Sind die Klassen gekürzt(umbenannt) worden?


    block_

    Klar ist das möglich ;)
    Einfach zwischen den beiden Handys bzw. zwischen Handy -> Server <- Handy eine Socketkommunikation aufbauen. Um nicht das Rad nicht neu zu erfinden (so eine Socketkommunikation kann Spaß machen, aber auch einen echt frustrieren..), kannste dir mal Netty angucken. Das Regelt für dich Dinge wie Verbindungsabbrüche etc., sodass du das nicht alles zu Fuß machen musst.


    Nun fordert PhoneA die Ip von PhoneB vom Server an und sendet dann an diese Ip das Datenpaket.


    Das sollte gehen, jedoch nur wenn der Server sich auch in deinen eigenen Netz befindet. Wenn du das ganze auch über Internet haben willst, wirste spätestens hier Probleme mit der Firewall bekommen. In dem Fall würd ich alles über den Server laufen lassen.


    block_

    Ich hab mir mal JavaFX für ein paar Minuten nur angeguckt, sieht recht interessant aus, hab aber zu wenig Zeit um weiter zu machen.


    Aber ich glaube nicht das JavaFX schon auf Android läuft. Soweit ich das gelesen hab, wurde das erst auf der letzten JavaOne angeschnitten, aber ob es demnächst kommt, ist eine andere Frage. Hab dazu jedenfalls nicht mehr viel gefunden.


    block_

    Beim Testen von meinem Vorschlag hat alles soweit funktioniert und es wurde keine Exception geworfen. Habs jetzt mit dem Emulator nochmal getestet und den Fehler beseitig.



    Client:


    Verbindung:


    Server:


    block_

    Da haben sich eine paar Fehler mit eingeschlichen, da ich das alles nur im Notepad geschrieben hab :P


    Den Konstruktor nochmal:


    Code
    public Verbindung() throws UnknownHostException, IOException {
    
    
    	socket = new Socket("192.168.2.3", 4444);
    	input = new BufferedReader(new InputStreamReader(
    			socket.getInputStream()));
    }


    und in deine onCreate schreibste folgendes:




    Hoffe das klappt jetzt so :)


    block_

    Also der Server sieht schon so okay aus.


    Client:


    Jetzt kannst du eine Instanz von Verbindung erstellen und durch die Methode start() einfach starten lassen.

    Code
    Verbindung verbindung = new Verbindung();
    verbindung.start();


    Nun sollte immer die aktualisierte Zahl vom Server empfangen werden, solange der Thread läuft. Das Senden an den Server kannste normal um UI-Thread weitermachen, wie du es vorher hattest. Durch stop() sollte, die Verbindung dann geschlossen werden. Allerdings wird durch die Blockierung von der readline()-Methode das Schließen erst ausgeführt, nachdem eine weitere Nachricht empfangen wurde und somit die Schleife beendet werden konnte. Es gibt noch eine andere Methoden einen Thread zu beenden und zwar mit Interrupts, jedoch konnt ich das noch nicht testen, weil mein Eclipse streikt.


    Zu den Tipps nochmal:
    Die Namenskonventionen besagen, dass Variablennamen am Anfang klein geschrieben werden sollen. Zum Beispiel "NachrichtText" -> "nachrichtText".
    Für den Leak: static final Handler myHandler {...}
    Und zu der Klasse Verbindung: Verschiebe diese besser ans Ende der Datei, dadurch kann man den Code besser lesen, da die Klasse ansonsten logischen Gedanken unterbricht und man diese gegebenenfalls auch suchen muss (in deinem Fall nicht besonders schwer zu finden, aber wenn das Projekt größer werden könnte, oder mehrere Instanzen von Verbindung an unterschiedlichen Stellen benutzt werden).


    Falls weitere Probleme auftauchen, sag bescheid :)


    block_