在Android中的BluetoothSocket inputstream.read()中实现超时

在Android中的BluetoothSocket inputstream.read()中实现超时,android,bluetooth,timeout,inputstream,Android,Bluetooth,Timeout,Inputstream,在Android中,是否可以从BluetoothSocket在inputstream.read()函数中实现超时 我尝试过使用Thread.sleep(),但这只会暂停我的活动 ---更新--- 我有一个想法,在这里创建两个线程代码读取(t1和t2),其中每个线程互相中断,其中一个(t1)进行睡眠(5000),然后中断另一个线程(t2),从另一端中断另一个线程(t2),如果在读取输入流时检测到某个字符为0x0D,则中断另一个线程(t1),但我的问题是,有人可以帮助我吗?因为我没有使用中断()方法

在Android中,是否可以从BluetoothSocket在inputstream.read()函数中实现超时

我尝试过使用Thread.sleep(),但这只会暂停我的活动

---更新---

我有一个想法,在这里创建两个线程代码读取(t1和t2),其中每个线程互相中断,其中一个(t1)进行睡眠(5000),然后中断另一个线程(t2),从另一端中断另一个线程(t2),如果在读取输入流时检测到某个字符为0x0D,则中断另一个线程(t1),但我的问题是,有人可以帮助我吗?因为我没有使用中断()方法的线程,我希望有人能帮助我,谢谢

---更新---

这是我的实现,当某个东西出现在不同的线程中时,问题是如果我没有从demminstream中获取0x3e字符,就会达到超时

我假设在第二个示例中,我必须使用notifyAll(),但是,我必须何时启动readThread()


谢谢,@weeman

你可以这样做:

InputStream in = someBluetoothSocket.getInputStream();
int timeout = 0;
int maxTimeout = 8; // leads to a timeout of 2 seconds
int available = 0;

while((available = in.available()) == 0 && timeout < maxTimeout) {
    timeout++;
    // throws interrupted exception
    Thread.sleep(250);
}

byte[] read = new byte[available];
in.read(read);
Thread readThread = new ReadThread(); // being a thread you use to read from an InputStream
try {
   synchronized (readThread) {
      // edit: start readThread here
      readThread.start();
      readThread.wait(timeOutInMilliSeconds);
   }
catch (InterruptedException e) {}
如果线程确实从输入流中读取了某些内容,那么您可能需要某种类型的事件处理程序来通知您的应用程序

我希望这有帮助

----编辑:

我实现了一个示例,没有使用任何处理程序

Socket s = new Socket("localhost", 8080);
    final InputStream in = s.getInputStream();

    Thread readThread = new Thread(new Runnable() {
        public void run() {
            int read = 0;
            try {
                while((read = in.read()) >= 0) {
                    System.out.println(new String(new byte[]{ (byte) read }));
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    });

    synchronized (readThread) {
        readThread.start();
        try {
            readThread.wait(2000);

            if(readThread.isAlive()) {
                                    // probably really not good practice!
                in.close();
                System.out.println("Timeout exceeded!");
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

用于带超时的套接字读取的Kotlin扩展函数:

fun InputStream.read(
  buffer: ByteArray,
  offset: Int,
  length: Int,
  timeout: Long
): Int = runBlocking {
    val readAsync = async {
        if (available() > 0) read(buffer, offset, length) else 0
    }
    var byteCount = 0
    var retries = 3
    while (byteCount == 0 && retries > 0) {
        withTimeout(timeout) {
            byteCount = readAsync.await()
        }
        delay(timeout)
        retries--
    }
    byteCount
}

就API而言,我没有遇到这样的方法。。。也许有一些反思的方法可以做到这一点。。。!?蓝牙套接字和inputstream都没有任何方法来实现超时。这就是我的问题,我已经尝试了线程和处理程序,但还无法实现。。。谢谢你的回答,你可以用“Trim()”而不是“replaceAll”(“,”)“非常好的超时实现,但我的代码中没有它,我已经更新了我的答案,如果你能帮我一把的话。。。谢谢顺便说一句,是的。你是对的。我将改变这一点,并尝试回答您更新的问题。感谢@weeman在阅读代码后,我了解此超时是如何工作的,如果我没有收到微控制器的响应,我可以实现一个超时,谢谢。。。
fun InputStream.read(
  buffer: ByteArray,
  offset: Int,
  length: Int,
  timeout: Long
): Int = runBlocking {
    val readAsync = async {
        if (available() > 0) read(buffer, offset, length) else 0
    }
    var byteCount = 0
    var retries = 3
    while (byteCount == 0 && retries > 0) {
        withTimeout(timeout) {
            byteCount = readAsync.await()
        }
        delay(timeout)
        retries--
    }
    byteCount
}