簡體   English   中英

用於捕獲BluetoothSocket InputStream.read()超時的線程

[英]Thread to catch a BluetoothSocket InputStream.read() timeout

我一直在使用InputStream.read( byte[] b, int off, int len )方法讀入數據,但現在已經遇到了超時問題。 我有時會期待閱讀超時,並且應該讓程序在超時后相應地調整自己。 我試圖實現一個Thread,但我對Threads一無所知,也無法讓它工作。 我還想補充一點,這個線程正在另一個線程中初始化。 我不確定這是什么意思,但它可能會導致問題。

我的初始代碼在我需要閱讀的大部分時間都有效,但每當我預計超時時,我的程序會在read()調用時凍結,並且永遠不會超時。 當我實現這個新代碼時,我的初始代碼工作的時間現在超時了。 我使用Thread.wait(500) ,我假設是500毫秒,但我找不到任何Javadocs,包括wait()函數。 這里這里

有關此的其他職位: 123

我還考慮過聲明BluetoothSocket的超時,但我在文檔中的任何地方都找不到它。

這是我的初始代碼:

public void run(int length) throws IOException {
        buffer = new byte[1024];
        try {
                bytes = mmInStream.read(buffer, 0, length);
                mHandler.obtainMessage(MainMenu.MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();
        } catch (IOException e) {
                Message msg = mHandler.obtainMessage(MainMenu.MESSAGE_TOAST);
                Bundle bundle = new Bundle();
                bundle.putString( TOAST, "Device has disconnected from the Bluetooth Module." );
                msg.setData(bundle);
                mHandler.sendMessage(msg);
                connectionLost();
                BluetoothService.this.start();
        }

這是我試圖實現的:

public void run(int length) throws IOException {
        buffer = new byte[1024];
        length1 = length;
        Thread myThread = new Thread(new Runnable() {
            public void run() {
                try {
                    bytes = mmInStream.read( buffer, 0, length1 );
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });

        synchronized (myThread) {
            myThread.start();
            try {
                myThread.wait(500);
                if(myThread.isAlive()) {
                    mmInStream.close();
                    Log.i( "InStream", "Timeout exceeded!");
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
       try {
            myThread.run();
            mHandler.obtainMessage(MainMenu.MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();
       } catch (IOException e) {
                Message msg = mHandler.obtainMessage(MainMenu.MESSAGE_TOAST);
                Bundle bundle = new Bundle();
                bundle.putString( TOAST, "Device has disconnected from the Bluetooth Module." );
                msg.setData(bundle);
                mHandler.sendMessage(msg);
                connectionLost();
                BluetoothService.this.start();
       }

編輯:

所以我正在嘗試重新創建

buffer = new byte[1024];
bytes = mmInStream.read(buffer, 0, length);

我做了以下事情:

Scanner scan = new Scanner(new InputStreamReader(mmInStream));
String readIn;
try {
    readIn = scan.next();
    bytes = 5; // I tried with or without this, since I do not think it matters...
    buffer = readIn.getBytes( Charset.forName( "US-ASCII" ) );
}

稍后在我的代碼中我打了這個電話....抱歉再次編輯, buf=read( 5 )調用轉到上面顯示的內容。

byte[] buf  = buffer;
write( a );
buf = read( 5 );
Log.i(TAG,  "Before buf[5]" );
try {
     buf[5] = '\0';
} catch( NullPointerException e ) {
    return false;
}

當我使用原始方法時,它會將此buf[5]調用通過。 但是當我使用new方法時,它會在那個位置給我一個IndexOutOfBoundsException 我錯過了什么嗎? 預期輸入應為CMD\\r\\n

藍牙聊天示例在這方面確實很差,你應該使用輸入掃描器而不是mmInStream.read。 這是我使用的,它運作得相當好......

對於您的用例,您可以跳過整個緩沖區和字節並進行寫入和讀取(當您使用掃描儀和輸入流程讀取器時,不需要使用任何這些,因為那些處理那些東西)...換句話說,下面的代碼需要注意這一切都適合你。 我把你的分隔符更改為CRLF。 下面的代碼是你發送一個字符串然后寫入然后讀取。 如果您不需要向遠程設備發送任何內容,只需從scan = new Scanner開始。 每次讀取一行並以\\ r \\ n結束時,它會將其存儲在字符串instring中。

所以如果你想發送“a”,你會寫

String readIn = beginListenForData("a");

a將在mmOutStream下發送,然后掃描器將讀取mmInStream並收集所有字符,然后一旦看到CRLF,它將返回它讀取的字符並將它們返回到readIn字符串中。 合理?

private String beginListenForData(String msg0) {
    msg0 += "\r"; //this adds a return character to the string, you can omit this if you just send an a and the remote device understands what that means.
    String instring = "";
    try {
        mmOutStream.write(msg0.getBytes());
    } catch (IOException ex) {              
        stop();
    }
    scan = new Scanner(new InputStreamReader(mmInStream));
    scan.useDelimiter(Pattern.compile("[\\r\\n]+"));
    instring = scan.next();
    scan = null;
    return instring;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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