Jos*_*ams 7 sockets android bluetooth blocking
我一直在研究一款适用于Android的蓝牙应用程序,我刚刚发现了这个问题.当我mySocket.connect();在我的蓝牙服务类中进行预处理时,它偶尔会无限期地阻塞.我阅读了文档,BluetoothSocket.close()并说明了以下内容:
立即关闭此套接字,并释放所有相关资源.
导致其他线程中此套接字上的被阻止调用立即抛出IOException.
但是,这对我来说似乎不起作用.这是我设置计时器然后尝试连接的代码.
//code for starting timer and connecting
MyRunnable runner = new MyRunnable(mySocket);
Thread countThread = new Thread(runner);
countThread.start();
mySocket.connect();
runner.setSocketConnected();
//code for MyRunnable
private class MyRunnable implements Runnable{
private boolean didSocketConnect = false;
private boolean socketConnectFailed = false;
private BluetoothSocket socket;
public MyRunnable(BluetoothSocket socket){
this.socket = socket;
}
public void run() {
long start = System.currentTimeMillis();
while(ESTABLISH_TIMEOUT + start >= System.currentTimeMillis() && !didSocketConnect && !socketConnectFailed){
}
if(!didSocketConnect && !socketConnectFailed){
Log.v(TAG,"Reached Timeout and socket not open. Look for #");
try {
socket.close();
Log.v(TAG,"#THIS CALL SHOULD BE MADE AFTER REACHED TIMEOUT AND SOCKET NOT OPEN");
} catch (IOException e) {
Log.v(TAG,"Closing the socket connection fail--", e);
}
}else{
Log.v(TAG, "Connected or Failed Before Timeout Thread Hit");
}
}
public void setSocketConnected(){
didSocketConnect = true;
}
public void setSocketFailed(){
socketConnectFailed= true;
}
}
Run Code Online (Sandbox Code Playgroud)
当我调用close()时,它也会无限期地阻塞,并且connect()调用永远不会抛出IOException,尽管有BluetoothSocket.close()文档.使它工作的最佳方法是什么,以便connect()和close()不会无限期地阻塞?
注意:我正在为此项目使用Android 2.2.
BluetoothSocket.connect() - 来自文档:
尝试连接到远程设备。该方法将阻塞,直到建立连接或连接失败。如果此方法返回且没有异常,则此套接字现在已连接。
为了让您对 BluetoothSocket.connect() 的调用退出阻塞,它需要建立连接。这是设计使然,如果您考虑一下,获取我们想要连接的蓝牙设备的地址,调用 .connect(),并阻塞直到其连接,这是有道理的。这就是为什么你需要单独的线程。
至于您调用 .close(),如果您解决了 .connect() 的问题,.close() 应该就位。
请阅读这个。它基本上表示您需要一个名为“连接”(.connect()) 和“已连接”(InputStream.read()) 的单独线程。这样你的 UI 就不会被阻塞。
示例(来自上面的链接)。ConnectThread 启动连接。ConnectedThread 管理连接(读/写数据等)。
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(mmSocket);
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main Activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main Activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14751 次 |
| 最近记录: |