我有一个第三方使用DatagramSocket进行设备发现,问题是当它在receive()模式下执行disconnect()时会阻塞线程。
我创建了一个类似的例子,在Android 7上运行并与Android 4.4.2之类的较低版本进行比较,结果是相同的:在Android 7上,断开连接阻塞线程,而在另一个版本上,它工作正常。谁能解释为什么会这样?是否有任何使用断开连接而不阻塞线程的解决方案?
DatagramSocket datagramSocket;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int server_port = 12345;
try {
datagramSocket = new DatagramSocket(server_port);
} catch (SocketException e) {
e.printStackTrace();
}
Button button = (Button)findViewById(R.id.buttonDisconnect);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG,"disconnect");
datagramSocket.disconnect();
Log.d(TAG,"close");
datagramSocket.close();
Log.d(TAG,"closed");
}
});
Button button2 = (Button)findViewById(R.id.buttonStart);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Thread t = new Thread() {
@Override
public void run() {
startDatagramSocket();
}
};
t.start();
}
});
}
private void startDatagramSocket() {
String text;
Log.d(TAG,"startDatagramSocket");
byte[] message = new byte[1500];
DatagramPacket p = new DatagramPacket(message, message.length);
try {
datagramSocket.receive(p);
text = new String(message, 0, p.getLength());
Log.d(TAG,"message:" + text);
datagramSocket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
执行startDatagramSocket()并断开连接导致:
Android 7:
10-26 17:52:55.349 ......:断开
和ANR,因为我使用了主线程
Android 4.4.2:
10-26 17:47:49.395 ......:断开
10-26 17:47:49.395 ......:关闭
10-26 17:47:49.395 ......:关闭
10-26 17:47:49.395 ...:java.net.SocketException:Socket closed
示例应用程序是重点,我没有像第三方那样添加到DataSocket的连接,但行为是可重现的。