簡體   English   中英

如果不使用,則在藍牙套接字上讀取的輸入流會掛起

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM