[英]Inputstream read on bluetooth socket hangs if not used
我正在开发一个与蓝牙设备通信的 Android 应用程序。
设备不断地向手机发送信息,但我选择仅在用户需要时读取数据:按开始/停止按钮。 每次都会启动/停止阅读服务,但连接保持打开状态。
无论按下多少次开始/停止按钮,与设备的连接都运行良好,但前提是用户不会让应用程序处于“停止”状态超过 5 秒。
如果用户让应用程序处于“停止”状态超过 5 秒,程序将在下次按下“开始”时卡在 inputstream.read() 中。
我已经检查过插座是否仍然打开。 我知道 read() 是一个阻塞函数,但在这种情况下它不应该阻塞,因为设备不断发送数据。
有没有人遇到过类似的问题? 问题真的有可能是因为socket在几秒钟内没有被使用吗?
这是我用于获取数据的代码:
public void start() {
if (isStarted()) {
return;
}
task = taskService.submit(new Runnable() {
@Override
public void run() {
int value;
channel.reset();
try {
while ((value = in.read()) != -1 && !Thread.currentThread().isInterrupted()) {
channel.put((byte) (value & 0xFF));
}
} catch (IOException e) {
Log.d("STRS", "IO error : " + e.getMessage(), e);
}
}
});
}
public void stop() {
if (!isStarted()) {
return;
}
task.cancel();
}
public boolean isStarted() {
return task != null && !task.isDone();
}
我在阻止来自蓝牙套接字的 read() 时遇到了类似的问题,并通过生成一个新线程并在紧密循环中调用 read() 将数据读入循环缓冲区来解决该问题。 您当前正在调用 read() 的线程现在从循环缓冲区读取数据,因此是非阻塞的,例如
private class ReceiveThread extends Thread {
private boolean running = true;
public void stopThread() {
running = false;
}
@Override
public void run() {
byte[] readBuffer = new byte[4 * 1024];
while (running) {
try {
// write bytes directly into a circular buffer
int numBytes = socket.read(readBuffer);
if (numBytes > 0) {
circularBuffer.put(readBuffer, 0, numBytes);
}
} catch (InterruptedIOException e) {
running = false;
} catch (Exception e) {
// swallow
}
}
}
}
然后您可以直接从循环缓冲区中读取
circularBuffer.get(buffer, 0, bytesToRead);
谷歌在 Java 中的循环缓冲区实现,有很多。 只要确保它是线程安全的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.