Java 如果未使用,蓝牙套接字上读取的Inputstream将挂起
我正在开发一款Android应用程序,它可以与蓝牙设备进行通信 该设备不断向手机发送信息,但我选择只在用户需要时读取数据:按下启动/停止按钮。每次都会启动/停止阅读服务,但连接保持打开状态 无论启动/停止按钮按下多少次,与设备的连接都能正常工作,但前提是用户不让应用程序处于“停止”状态超过5秒 如果用户让应用程序处于“停止”状态超过5秒,程序将在下次按下“开始”时卡在inputstream.read()中。 我检查过插座是否还开着。 我知道read()是一个阻塞函数,但在这种情况下,它不应该阻塞,因为设备正在连续发送数据 有没有人遇到过类似的问题?这个问题是否真的可能是因为插座在几秒钟内没有使用 以下是我用于获取数据的代码位:Java 如果未使用,蓝牙套接字上读取的Inputstream将挂起,java,android,sockets,bluetooth,inputstream,Java,Android,Sockets,Bluetooth,Inputstream,我正在开发一款Android应用程序,它可以与蓝牙设备进行通信 该设备不断向手机发送信息,但我选择只在用户需要时读取数据:按下启动/停止按钮。每次都会启动/停止阅读服务,但连接保持打开状态 无论启动/停止按钮按下多少次,与设备的连接都能正常工作,但前提是用户不让应用程序处于“停止”状态超过5秒 如果用户让应用程序处于“停止”状态超过5秒,程序将在下次按下“开始”时卡在inputstream.read()中。 我检查过插座是否还开着。 我知道read()是一个阻塞函数,但在这种情况下,它不应该阻塞
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);
Google对于Java中的循环缓冲区实现,有很多。只需确保它是线程安全的。我猜您通过中断线程来停止从流中读取,这可能是一个问题。另外,您如何跟踪状态(已启动/已停止)?此函数位于一个读取服务中,用户每次按start/stop时都会创建/销毁该服务,因此每次都会创建和销毁线程。为什么这会是个问题?我编辑了我的帖子以包含isStarted函数。这可能是一个问题,因为另一个线程可以清除
线程的中断标志,但从您发布的代码来看,情况似乎并非如此。我看到的一个问题是,您没有使用任何类型的同步来设置/检查状态。但为什么这会使程序卡在read()函数中?只有在程序处于非活动状态几秒钟的情况下,TCP套接字也可能发生类似的情况,如果您不打算使用它,则应在进入后台时关闭连接。