I'm writing an Android app that communicates with a PC via bluetooth. During normal operation, it sends out a rapid succession of short 8 byte packets from the Phone to the PC, typically at >100Hz.
On each device, a separate thread is running that execute writes and reads. The code looks like this:
/**
* The Class ProcessConnectionThread.
*/
public class ConnectedThread extends Thread {
/** The m connection. */
private StreamConnection mmConnection;
InputStream mmInputStream;
OutputStream mmOutputStream;
private boolean mmCanceled = false;
/**
* Instantiates a new process connection thread.
*
* @param connection
* the connection
*/
public ConnectedThread(StreamConnection connection) {
mmConnection = connection;
// prepare to receive data
try {
mmInputStream = mmConnection.openInputStream();
mmOutputStream = mmConnection.openOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Thread#run()
*/
@Override
public void run() {
byte[] buffer;
int bytes;
// Keep listening to the InputStream while connected
while (!mmCanceled) {
try {
buffer = ByteBufferFactory.getBuffer();
// Read from the InputStream
bytes = mmInputStream.read(buffer);
if(bytes > 0)
onBTMessageRead(buffer, bytes);
else
ByteBufferFactory.releaseBuffer(buffer);
} catch (IOException e) {
MyLog.log("Connection Terminated");
connectionLost();//Restarts service
break;
}
}
if(!mmCanceled){
onBTError(ERRORCODE_CONNECTION_LOST);
}
}
/**
* Write to the connected OutStream.
*
* @param buffer
* The bytes to write
* @param length
* the length
*/
public void write(byte[] buffer, int length) {
try {
mmOutputStream.write(buffer, 0, length);
// Share the sent message back to the UI Activity
onBTMessageWritten(buffer, length);
} catch (IOException e) {
MyLog.log("Exception during write:");
e.printStackTrace();
}
}
/**
* Cancel.
*/
public void cancel() {
try {
mmCanceled = true;
mmInputStream.close();
mmConnection.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
The Android side code is almost identical, just using a BluetoothSocket instead of a Stream Connection.
The big difference is in the onBTMessageRead(buffer, bytes);
Android function:
protected void onBTMessageRead(byte[] buffer, int length) {
if (mHandler != null) {
mHandler.obtainMessage(BluetoothService.MESSAGE_READ, length, -1,
buffer).sendToTarget();
}
}
PC Server Function:
protected void onBTMessageRead(byte[] message, int length) {
if (mEventListener != null) {
mEventListener.onBTMessageRead(message, length);
}
// Release the buffer
ByteBufferFactory.releaseBuffer(message);
}
Android provides a handler-looper/message pattern that allows messages to be sent across threads. This allows the reads to happen as fast as possible and queues the message processing in another thread. My ByteBufferFactory ensures that the resources are shared properly between threads.
Currently I only have an event listener pattern implemented on the PC side, but I would like a similar message passing pattern on the PC side too. Currently the event listener is bogging down the ConnectedThread and causing major communication lag.
Is there any way to send messages from one thread in java and have them handled asynchronously in another thread in FIFO order?