我正在制作一个安卓应用程序,它将通过蓝牙在手机之间进行通信。为了节省电池,我想避免一直打开蓝牙连接。所以每次我要发送消息时,我都会打开一个连接,发送消息,刷新,然后关闭。
我的问题是,有时,但并非总是,接收电话会给我臭名昭著的“java.io.IOException:bt socket closed,读取返回:-1”。我看到BluetoothSocket 文档指出
BluetoothSocket 是线程安全的。特别是,close() 总是会立即中止正在进行的操作并关闭套接字。
但是,一般蓝牙页面指出:
完成 BluetoothSocket 后,请始终调用 close()。这样做会立即关闭连接的套接字并释放所有相关的内部资源。
这是我发送消息的线程的摘录。
localSocket = device.createRfcommSocketToServiceRecord(MY_UUIDS[0]);
localSocket.connect();
Log.d(TAG, "Correctly Connected on " + MY_UUIDS[0]);
OutputStream rawOutputStream = localSocket.getOutputStream();
ObjectOutputStream messageOutputStream = new ObjectOutputStream(rawOutputStream);
// Actually send the message
messageOutputStream.writeObject(message);
messageOutputStream.flush();
rawOutputStream.flush();
messageOutputStream.close();
rawOutputStream.close();
localSocket.close();
这是我接受传入连接的线程的摘录:
InputStream rawInputStream = socket.getInputStream();
ObjectInputStream messageInputStream = new ObjectInputStream(rawInputStream);
BluetoothMessage joinMessage = (BluetoothMessage) messageInputStream.readObject();
BluetoothDevice device = socket.getRemoteDevice();
messageInputStream.close();
rawInputStream.close();
socket.close();
socket = null;
我意识到刷新和关闭是多余的,但事实是,有时由于硬件延迟,套接字在发送所有消息之前在发送端关闭。
我可以确认所有消息每次都完美到达,无论我发送它们的速度有多快......如果我不关闭套接字。但是,我知道关闭套接字始终是最佳做法。
那么如何确保在调用 socket.close() 之前发送所有消息?显然,flush() 和流 close() 没有做它们应该做的事情,否则,无论我何时调用 socket.close(),消息都会被完全发送。