2

我用姜饼。我已经与本地串行端口(RS-232 本地 UART,而不是 USB 加密狗)交谈。这是通过 java.io 和一小段用 C 编写的本机代码来完成的,用于打开和关闭流并配置波特率。它可以工作,但我的第一个想法是它效率不高,因为我需要设置一个线程来不断轮询输入流以检查是否有来自串行端口的字节。使用 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 接口在 C 中完成的,它在没有标志“NOBLOCK/NODELAY”的情况下打开。因此,它不应该在 while 循环中不断旋转,而只是在 mInputStream.read 上被阻塞,并且内核应该切换到另一个线程,直到有一些数据可供读取。在这种情况下,这段代码完全没问题。这个假设是真的吗?

我想知道,因为我的嵌入式系统的主要目的是大多数时间显示视频,我不希望我在幕后管理的内容占用太多资源并在视频播放中出现一些问题。

4

2 回答 2

2

在编写应用程序和测试之后,我可以说问题中的最后一个假设实际上是正确的。如果设备在没有标志“NOBLOCK/NODELAY”的情况下打开,线程将在 mInputStream.read() 上挂起,直到有可用数据。没有浪费的投票。

于 2012-11-16T21:03:18.463 回答
0

您可以使用 java.nio 包中的 selector()。

http://developer.android.com/reference/java/nio/channels/Selector.html

另请参阅http://www.drdobbs.com/jvm/high-performance-io-with-java-nio/184406242

于 2012-10-16T03:40:36.830 回答