Android 使用套接字时崩溃 Java

Android crash using socket Java

我尝试创建一个连接到服务器的应用程序,以便在每次收到来自服务器的消息时发送通知。 我创建了一个简单的客户端,它在服务器断开连接之前读取收到的消息。它使用 "Normal" Java 工作,但是当我将相同的代码放入 android 的 Button 事件中时,它崩溃了。 我认为这是来自 android 处理异常的方式,但我不同意。

代码

Start.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

            String notif = "";

            try {
                //Get the server info from 2 Text Field
                socket = new Socket(IpServer.getText().toString(),Integer.parseInt(PortServer.getText().toString()));

                //While the server is connected it read
                while (socket.getInputStream().read() != -1){

                    in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                    //If the message is different to the one before
                    if(!notif.equals(notif = in.readLine())) {

                        if(!alarm.isChecked()) {

                            //Send a notification
                            createNotification(notif);

                        }else if(alarm.isChecked()){

                            //Send a notification and play a ringtone

                            createNotification(notif);

                            Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);

                            Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);

                            r.play();

                        }
                    }
                    try{

                        Thread.sleep(1000);

                    }catch(InterruptedException e){

                        error.setText("         That's wierd");

                    }
                }

                socket.close();

            }catch (UnknownHostException e) {

                error.setText("         This IP is unreachable");

            }catch (IOException e) {

                error.setText("         This IP is unreachable");

            }
        }
    });

崩溃信息:

    --------- beginning of crash
06-29 08:36:24.620 4325-4325/com.example.nxf44628.notificationextender E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.nxf44628.notificationextender, PID: 4325
    android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
        at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:110)
        at libcore.io.IoBridge.connectErrno(IoBridge.java:137)
        at libcore.io.IoBridge.connect(IoBridge.java:122)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:163)
        at java.net.Socket.startupSocket(Socket.java:592)
        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.example.nxf44628.notificationextender.MainActivity.onClick(MainActivity.java:76)
        at android.view.View.performClick(View.java:5198)
        at android.view.View$PerformClick.run(View.java:21147)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

使用

<uses-permission android:name="android.permission.INTERNET"/>

在你的androidManifest.xml

这里的link类似于question

还将按钮侦听器中的所有内容移至线程或服务。

您的代码的问题是它在主线程上建立连接(套接字),也就是 UI 线程,这是不允许的。

相反,我们必须将网络调用包装在后台线程中,这样就不会对应用产生影响。

您有多种方法可以做到这一点。

  • 使用处理程序。
  • 异步任务
  • 意图和后台服务
  • 使用响应式编程和所有相关的优秀库。

Here 是关于异步任务的基本示例