2

Simple question - is there a way to have an event that is triggered the moment data arrives on an input stream?

In our open source project we're just looping until we see an end of message character (piecing togegher the message along the way). The loop pauses 300ms between loops to reduce CPU utilization but this is still a far cry from "event driven programming".

sleeping too long is detrimental to throughput sleeping too short is detrimental to CPU, other processes, and context-switch intensive.

I'd like to clean up the readUpToCharacter function in the above link so that it waits for data in an event driven manner.

Looking for some clever design patterns for this seemingly common problem.

Thanks!!!

Brad Hein
  • 10,997
  • 12
  • 51
  • 74

2 Answers2

2

Start a new thread that does a blocking read and have it raise an event whenever data arrives?

alanjmcf
  • 3,430
  • 1
  • 17
  • 14
  • Man thats a great idea - simple, elegant. I didnt think read() blocked this way but a quick refresher suggests it does. Thanks! – Brad Hein Jun 16 '11 at 03:36
  • Note to others reading this that it would be a good idea to put a limit on the length of time that the thread waits for data. For example if the remote device goes offline, you wouldn't want to block the thread infinitely. My thought is that a separate thread perhaps can run Thread.interrupt() against the blocking thread to unblock it after a timeout expires. – Brad Hein Jun 17 '11 at 17:59
  • @alanjmcf you could elaborate a bit on how to do what you suggested. I know its searchable, but why force users to do another search? You clearly know how to do this, take the 5 min needed to write it down. Also, skip the qeustion mark at the end of the answer - it makes it look condescending. – K.L. Jun 17 '13 at 12:20
  • @K.L. I don't think the question mark makes the answer appear condescending. Threads can be tricky (especially a thread that's calling a blocking method) and I could see why alanjmcf might be hesitant to offer it up. It certainly would take more than 5 minutes to type up a solution using threads, as you can see from the OP's 17 June comment. Besides, if you don't understand the proposed solution then you shouldn't be playing with threads. – Paul Aug 18 '14 at 02:47
  • As it is mentioned in the comments an example of such a thread can be found here in the android documentation http://developer.android.com/guide/topics/connectivity/bluetooth.html – Martin O'Shea Jan 09 '16 at 19:24
1

Depending on the input stream (if it is one with an underlying file descriptor) you may be able to use the NIO Selector classes to wait for the file descriptor to become ready for reading.

Unfortunately the Bluetooth streams provided on Android do not provide access to the underlying file descriptor and the available method does not work reliably from one Android device to the other so it is currently not possible to do what you want from Java code.

EDIT: I should note that the InputStream.available method DOES work on some Android devices (in my experience the Nexus 1 and earlier HTC devices that use Google's Android Bluetooth port implementation do fine; Samsung and more recent HTC devices that use vendor-supplied Bluetooth port implementations fail woefully) so if your application will be deployed on a known subset of devices you might do well with this option.

Femi
  • 64,273
  • 8
  • 118
  • 148
  • Thanks @Femi - I'll check out NIO selector classes. I think you may have pointed out the solution to another issue I had, with HTC Bluetooth, described here: http://stackoverflow.com/questions/2853790 - Thanks! :) – Brad Hein Jun 12 '11 at 14:20