gpt4 book ai didi

java - Android BluetoothSocket - 超时

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:08:33 24 4
gpt4 key购买 nike

我已经编写了一个用于连接外部配件的蓝牙 API。API 的设计方式是有一堆阻塞调用,例如 getTimesetTimegetVolumesetVolume等这些工作的方式是它们创建一个有效负载来发送和调用一个名为 sendAndReceive() 的方法,该方法会做一些准备工作并最终执行以下操作:

byte[] retVal = null;
BluetoothSocket socket = getSocket();
// write
socket.getOutputStream().write(payload);
// read response
if(responseExpected){
byte[] buffer = new byte[1024]; // buffer store for the stream
int readbytes = socket.getInputStream().read(buffer);
retVal = new byte[readbytes];
System.arraycopy(buffer, 0, retVal, 0, readbytes);
}
return retVal;

问题是有时此设备会变慢或无响应,因此我想在此调用上设置超时。我尝试了几种将此代码放入线程\ future 任务并超时运行的方法,例如:

FutureTask<byte[]> theTask = null;
// create new task
theTask = new FutureTask<byte[]>(
new Callable<byte[]>() {

@Override
public byte[] call() {
byte[] retVal = null;
BluetoothSocket socket = getSocket();
// write
socket.getOutputStream().write(payload);
// read response
if(responseExpected){
byte[] buffer = new byte[1024]; // buffer store for the stream
int readbytes = socket.getInputStream().read(buffer);
retVal = new byte[readbytes];
System.arraycopy(buffer, 0, retVal, 0, readbytes);
}
return retVal;
}
});

// start task in a new thread
new Thread(theTask).start();

// wait for the execution to finish, timeout after 6 secs
byte[] response;
try {
response = theTask.get(6L, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new CbtException(e);
} catch (ExecutionException e) {
throw new CbtException(e);
} catch (TimeoutException e) {
throw new CbtCallTimedOutException(e);
}
return response;
}

这种方法的问题是我不能在调用方法中重新抛出异常,并且由于某些方法抛出异常我想转发回 API 的客户端,所以我不能使用这种方法。

你能推荐一些其他的选择吗?谢谢!

最佳答案

你正在保存你不能使用 Future<> 方法,因为你想重新抛出异常,但实际上这是可能的。

大多数在线示例确实使用原型(prototype) public 实现了 Callable ? call() 但只是将其更改为 public ? call() 抛出异常,一切都会好起来的:您将在 theTask.get() 调用中得到异常,您可以将其重新抛给调用者。

我个人使用 Executors 来处理 android 上的蓝牙套接字超时:

protected static String readAnswer(...)
throws Exception {
String timeoutMessage = "timeout";
ExecutorService executor = Executors.newCachedThreadPool();
Callable<String> task = new Callable<String>() {
public String call() throws Exception {
return readAnswerNoTimeout(...);
}
};
Future<String> future = executor.submit(task);
try {
return future.get(SOCKET_TIMEOUT_MS, TimeUnit.MILLISECONDS);
} catch (TimeoutException ex) {
future.cancel(true);
throw new Exception(timeoutMessage);
}
}

关于java - Android BluetoothSocket - 超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6346649/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com