使用套接字Java导致Android崩溃

时间:2018-06-29 08:24:24

标签: java android sockets client

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

代码

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$1.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)

2 个答案:

答案 0 :(得分:1)

您的代码的问题在于它正在通过主线程(即UI线程)建立连接(套接字)。

相反,我们必须将网络调用包装在后台线程中,以免对应用程序造成影响。

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

  • 使用处理程序。
  • 异步任务
  • 意图和后台服务
  • 使用反应式编程和所有出色的库。

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

答案 1 :(得分:0)

使用

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

在您的androidManifest.xml

在此链接到相似的question

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