[英]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.