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 是关于异步任务的基本示例
我尝试创建一个连接到服务器的应用程序,以便在每次收到来自服务器的消息时发送通知。 我创建了一个简单的客户端,它在服务器断开连接之前读取收到的消息。它使用 "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 是关于异步任务的基本示例