Frage von YellowEagle, 31

Android SSH Verbindung mit JSCH, Fehler?

Ich bastle momentan an einer App mit der ich SSH Befehle an meinen Raspberry senden will das Problem ist jetzt das ich mich mit SSH in Java noch nicht wirklich auseinander gesetzt habe. Ich habe es jetzt aber "geschaft" ein Script zu finden ein zu bauen und auf zu rufen aber es gibt immer einen Fehler (es könnte auch am Emulator liegen aber das weis ich auch nicht so genau). Hier der Code + Fehler: http://pastebin.com/VDqKkYbK

Antwort
von MalNachgedacht, 19

Aus dem Fehlerprotokoll:

    04-22 04:52:17.311 2327-2327/com.example.luick.boat_rc W/System.err: com.jcraft.jsch.JSchException: android.os. NetworkOnMainThreadException

In Android ist der main-Thread für das Benutzerinterface verantwortlich. Deswegen wird er auch oft UI-Thread genannt.

Dieser UI-Thread ist eine Schleife die Nachrichten aus einer message-queue abarbeitet - wobei die Nachrichten z.B. Events sind die generiert werden wenn der Nutzer den Touchscreen berührt.

Jede Operation die länger benötigt und im main/UI-Thread stattfindet würde die Verarbeitung solcher Nachrichten zeitweise blockieren - und löst dann auch nach einer gewissen Zeit einen ANR (Application not responding) Error aus.

Bei Operation die irgendetwas per Netzwerk machen wird generell unterstell dass sie womöglich lange dauern - und entsprechend sind sie im main-Thread verboten bzw. verursachen dort obige Exception...

Du mußt also einen separaten Thread erzeugen der sich um die Datenübertragung kümmert.....

Kommentar von YellowEagle ,

Danke für die schnelle Antwort.

Aber und wie mach ich das?

Kommentar von MalNachgedacht ,

Prinzipiell dadurch dass Du eine Unterklasse (z,B, "RaspberryThread") der Klasse "Thread" erstellst und dort die Methode run() überschreibst.
Innerhalb von run() findet dann die Netzwerkkommunikation statt-

Damit der Thread zum Laufen kommt erstellst Du ein entsprechenden Objekt

RaspberryThread x=new RaspberryThread();

und startest diesen Thread mit

x.start()

Nun führt Android die run() Methode im "Hintergrund" aus. Dieser Hintergrund-Thread läuft solange bis die run() Methode endet.
Je nach dem wie die Kommunikation aussehen soll kann die run() Methode als Endlosschleife angelegt sein.

Das Problem ist jetzt, dass der main-Thread normalerweise irgendwie mit dem Hintergrund-Thread kommunizieren muß.

Der Benutzer gibt z.B. irgendeinen Befehl ein (im UI-Thread)- der dann von diesem Hintergrund-Thread zum Raspberry gesendet werden soll.
Also muß der entsprechende Befehl vom main-Thread zum Hintergrund-Thread gelangen.
Eine simple Lösung wäre z.B. eine Member-Variable in der Unterklasse RaspberryThread wie "String executeCommand"

Mit 

x.executeCommand="Do something on the rasperry";

könnte man dann einen Befehl an den Thread (der ja durch x dargestellt wird übergeben

die run() Methode in RaspberryThread könnte dann z.B. so aussehen

void run(){

while (true){

if (executeCommand==null){

  Thread.sleep(100);

} else {

  SendCommandToRaspberry(executeCommand);

  executeCommand==null

}

}

}

Im UI-Thread muss man dann prüfen ob x.executeCommand==null ist bevor man den nächsten Befehl übergibt.
Sobald der dann vom Hintergrund-Thread abgearbeitet wurde wird executeCommand dann ja von diesem auf null gesetzt und der UI-Thread weiß dass er jetzt den nächsten Befehl übergeben darf.
Bei länger dauernden Befehlen möchte man dem Benutzer vielleicht eine Art Fortschrittsbalken anzeigen.
Dann muß der Hintergrund-Thread irgendeine Variable auf den aktuellen Fortschrittsstand in Prozenz setzen die dann vom UI-Thread z.B. alle 100 ms ausgelesen wird um ggf. dann einen entsprechend View (ProgressBar) auf den neuesten Stand zu bringen.

Wenn Du noch nie mit Threads zu tun hattest ist das anfangs eine ziemlich neue Denkweise mit Fehlermöglichkeiten die es bei normaler Programmierung gar nicht gibt...
Man sollte sich zumindest die wichtigsten Grundlagen aneignen und selbst dann ist das alles andere als trivial. 

Kommentar von YellowEagle ,

Ok, die Frage ist vielleicht ein bissche dreist aber könntest du meinen Code so abändern das es passt. Ich weis das man durch Versuchen lernt aber ich habe keine Zeit mehr. Ich arbeite an einem größeren Projekt und sollte das bis morgen geschafft haben.... Ich hätte nicht gedacht das dass so kompliziert ist.

Ich habe zwar schon mit Threads zu tun gehabt also Multiblethread handling für Clientanfragen mit Java oder C++ doch habe ich keine Zeit mehr....

Ich würde mich über eine Antwort freuen.

MFG Luick.

Kommentar von YellowEagle ,

Ich habe selbst eine Lösung gefunden dank deiner Anregung danke :D

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten