【问题标题】:no InputStream data arrived event?没有 InputStream 数据到达事件?
【发布时间】:2011-06-12 03:58:47
【问题描述】:

简单的问题 - 有没有办法在数据到达输入流时触发事件?

our open source project 中,我们只是循环,直到我们看到消息字符的结尾(沿途将消息拼接在一起)。循环在循环之间暂停 300 毫秒以降低 CPU 利用率,但这与“事件驱动编程”仍然相去甚远。

睡眠时间过长不利于吞吐量 睡眠时间过短对 CPU、其他进程和上下文切换密集型都是有害的。

我想清理上面链接中的readUpToCharacter 函数,以便它以事件驱动的方式等待数据。

为这个看似常见的问题寻找一些巧妙的设计模式。

谢谢!!!

【问题讨论】:

    标签: java android stream bluetooth


    【解决方案1】:

    启动一个执行阻塞读取的新线程并让它在数据到达时引发事件?

    【讨论】:

    • 这真是个好主意——简单、优雅。我不认为 read() 会以这种方式阻止,但快速复习表明确实如此。谢谢!
    • 请注意阅读本文的其他人,最好限制线程等待数据的时间长度。例如,如果远程设备离线,您不希望无限阻塞线程。我的想法是,一个单独的线程也许可以对阻塞线程运行 Thread.interrupt() 以在超时到期后解除阻塞。
    • @alanjmcf 您可以详细说明如何按照您的建议进行操作。我知道它是可搜索的,但为什么要强迫用户进行另一次搜索呢?你清楚地知道怎么做,花 5 分钟把它写下来。另外,请跳过答案末尾的问号 - 它看起来居高临下。
    • @K.L.我不认为问号会使答案显得居高临下。线程可能很棘手(尤其是调用阻塞方法的线程),我可以理解为什么 alanjmcf 可能不愿提供它。从 OP 的 6 月 17 日评论中可以看出,使用线程输入解决方案肯定需要 5 分钟以上的时间。此外,如果您不理解建议的解决方案,那么您不应该使用线程。
    • 正如 cmets 中提到的那样,可以在 android 文档developer.android.com/guide/topics/connectivity/bluetooth.html 中找到此类线程的示例@
    【解决方案2】:

    根据输入流(如果它是带有底层文件描述符的输入流),您可以使用 NIO 选择器类等待文件描述符准备好读取。

    不幸的是,Android 上提供的蓝牙流不提供对底层文件描述符的访问,并且available 方法不能可靠地从一台 Android 设备到另一台设备,因此目前无法通过 Java 代码执行您想要的操作.

    编辑:我应该注意InputStream.available 方法确实适用于某些 Android 设备(根据我的经验,使用 Google 的 Android 蓝牙端口实现的 Nexus 1 和更早的 HTC 设备运行良好;三星和使用供应商的更新的 HTC 设备- 提供的蓝牙端口实现严重失败)因此,如果您的应用程序将部署在已知的设备子集上,您可能会使用此选项做得很好。

    【讨论】:

    • 谢谢@Femi - 我会检查 NIO 选择器类。我想你可能已经指出了我在 HTC 蓝牙中遇到的另一个问题的解决方案,如下所述:stackoverflow.com/questions/2853790 - 谢谢! :)
    猜你喜欢
    • 2012-05-30
    • 2011-11-29
    • 2011-09-10
    • 2015-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    相关资源
    最近更新 更多