我用 Gingerbread 。我已经与 native 串行端口(RS-232 native UART,而不是 USB dungle)进行通信。这是通过 java.io 和一小段用 C 编写的 native 代码来完成的,用于打开和关闭流并配置波特率。它有效,但我的第一个想法是它效率不高,因为我需要设置一个线程来不断轮询输入流以检查是否有来自串行端口的字节。这是多么浪费 CPU 和电池的使用方式。
private InputStream mInputStream;
private ReadThread mReadThread;
private class ReadThread extends Thread {
@Override
public void run() {
super.run();
while(!isInterrupted()) {
int size;
try {
byte[] buffer = new byte[64];
if (mInputStream == null) return;
size = mInputStream.read(buffer);
if (size > 0) {
onDataReceived(buffer, size);
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}
我认为我需要做的是拥有与 android 中其他事件相同类型的信号,我可以在其中设置某种监听器,该监听器将允许我收到即将到来的一些字节的通知并唤醒我的线程,这将处理传入的数据。我在 API 中没有找到类似的内容。
但是,经过更多的查看和研究后,最后,我认为这并不是浪费,但我想听听了解 Android 中线程如何工作的人的意见。让我们看一下代码行。
size = mInputStream.read(buffer);
实际上是阻塞读。我查看了设备是如何打开的,它是通过 NDK/JNI 接口(interface)用 C 语言完成的,并且它是在没有“NOBLOCK/NODELAY”标志的情况下打开的。因此,它不应该在 while 循环中不断旋转,而只是在 mInputStream.read 上被阻塞,并且内核应该切换到另一个线程,直到有一些数据可供读取。在这种情况下,这段代码就完全没问题了。这个假设正确吗?
我想知道这一点,因为我的嵌入式系统大部分时间的主要目的是显示视频,我不希望我在幕后管理的内容占用大量资源并在视频中出现一些问题回放。
最佳答案
编写应用程序并进行测试后,我可以说问题中的最后一个假设实际上是正确的。如果设备在没有“NOBLOCK/NODELAY”标志的情况下打开,则线程将在 mInputStream.read() 上挂起,直到有数据可用。没有浪费的轮询。
关于android - 无需轮询即可访问串行端口 (/dev/tty*) 传入数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12906831/