Hallo,
ich möchte gerne eine Android-App in Java programmieren, die sich zunächst mit einem Server im WLAN-Netzwerk verbindet. Später sollen dann Daten zwischen Server und Client hin und her geschickt werden.
Auf dem Handy soll also die App als Client laufen und sich über einen
mit dem Server verbinden. Das ganze sieht auf dem Handy folgendermaßen aus:
Wenn der Connect-Button geklickt wird, soll von der App eine Verbindung zum Server hergestellt werden und auf einem Label (
) ausgegeben werden, dass die Verbindung erfolgreich hergestellt werden konnte oder auch nicht hergestellt werden konnte.
Jetzt zu meinem Problem:
Ich darf ich in einer Android-App keine Netzwerkverbindung im Main-Thread herstellen, dann gibt es eine
.
Daher habe ich das Erstellen des neuen Sockets einen neuen Thread verlegt und starte diesen beim Aufruf der Button-Click-Methode, so wie ich es normalerweise in Java auch mache, damit die graphische Oberfläche nicht während der Laufzeit der Button-Click-Methode blockiert ist. Wenn ich aber dann von diesem Thread aus den Text eines Labels ändern will, bekomme ich auch eine Fehlermeldung, und zwar eine
, weil ich den Text eines Labels nur aus dem Thread ändern darf, in dem ich es auch ereugt habe, also nur vom MainThread.
Wie soll ich denn so eine Verbindung erstellen und danach auf einem Label ausgeben, ob die Verbindung erfolgreich war. Meine einzige Lösung wäre, eine Warteschliefe in der Button-Click-Methode zu erstellen, die wartet, bis die Verbindung erstellt wurde. Allerdings ist dann die Graphische Oberfläche die ganze Zeit blockiert. Kennt sich vielleicht jemand mit der Android-Programmierung aus und kann mir weiterhelfen? Gibt es da auch eine schönere Lösung?
PS: Der Server wird auf dem Computer gestartet und funktioniert bereits. Sobald sich ein Client verbindet, zeigt der Server dies an.
ich möchte gerne eine Android-App in Java programmieren, die sich zunächst mit einem Server im WLAN-Netzwerk verbindet. Später sollen dann Daten zwischen Server und Client hin und her geschickt werden.
Auf dem Handy soll also die App als Client laufen und sich über einen
Code:
java.net.Socket
Wenn der Connect-Button geklickt wird, soll von der App eine Verbindung zum Server hergestellt werden und auf einem Label (
Code:
android.widget.TextView
Jetzt zu meinem Problem:
Ich darf ich in einer Android-App keine Netzwerkverbindung im Main-Thread herstellen, dann gibt es eine
Code:
android.os.NetworkOnMainThreadException
05-27 18:33:02.422 15805-15805/com.musicstream.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.musicstream.app, PID: 15805
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1156)
at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
at libcore.io.IoBridge.connect(IoBridge.java:112)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.Socket.startupSocket(Socket.java:566)
at java.net.Socket.tryAllAddresses(Socket.java:128)
at java.net.Socket.<init>(Socket.java:178)
at java.net.Socket.<init>(Socket.java:150)
at com.musicstream.app.Verbindung.<init>(Verbindung.java:61)
at com.musicstream.app.MainActivity.btnConnectClick(MainActivity.java:115)
at com.musicstream.app.MainActivity.access$400(MainActivity.java:19)
at com.musicstream.app.MainActivity$2.onClick(MainActivity.java:65)
at android.view.View.performClick(View.java:4633)
at android.view.View$PerformClick.run(View.java:19330)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
Process: com.musicstream.app, PID: 15805
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1156)
at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
at libcore.io.IoBridge.connect(IoBridge.java:112)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.Socket.startupSocket(Socket.java:566)
at java.net.Socket.tryAllAddresses(Socket.java:128)
at java.net.Socket.<init>(Socket.java:178)
at java.net.Socket.<init>(Socket.java:150)
at com.musicstream.app.Verbindung.<init>(Verbindung.java:61)
at com.musicstream.app.MainActivity.btnConnectClick(MainActivity.java:115)
at com.musicstream.app.MainActivity.access$400(MainActivity.java:19)
at com.musicstream.app.MainActivity$2.onClick(MainActivity.java:65)
at android.view.View.performClick(View.java:4633)
at android.view.View$PerformClick.run(View.java:19330)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
Code:
android.view.ViewRootImpl$CalledFromWrongThreadException
05-27 18:59:00.973 19873-19962/com.musicstream.app E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-16367
Process: com.musicstream.app, PID: 19873
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6909)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1054)
at android.view.View.requestLayout(View.java:17321)
at android.view.View.requestLayout(View.java:17321)
at android.view.View.requestLayout(View.java:17321)
at android.view.View.requestLayout(View.java:17321)
at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:352)
at android.view.View.requestLayout(View.java:17321)
at android.widget.TextView.checkForRelayout(TextView.java:8003)
at android.widget.TextView.setText(TextView.java:4840)
at android.widget.TextView.setText(TextView.java:4672)
at android.widget.TextView.setText(TextView.java:4647)
at com.musicstream.app.MainActivity$3.run(MainActivity.java:155)
at java.lang.Thread.run(Thread.java:841)
Process: com.musicstream.app, PID: 19873
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6909)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1054)
at android.view.View.requestLayout(View.java:17321)
at android.view.View.requestLayout(View.java:17321)
at android.view.View.requestLayout(View.java:17321)
at android.view.View.requestLayout(View.java:17321)
at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:352)
at android.view.View.requestLayout(View.java:17321)
at android.widget.TextView.checkForRelayout(TextView.java:8003)
at android.widget.TextView.setText(TextView.java:4840)
at android.widget.TextView.setText(TextView.java:4672)
at android.widget.TextView.setText(TextView.java:4647)
at com.musicstream.app.MainActivity$3.run(MainActivity.java:155)
at java.lang.Thread.run(Thread.java:841)
PS: Der Server wird auf dem Computer gestartet und funktioniert bereits. Sobald sich ein Client verbindet, zeigt der Server dies an.