2

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?

CodeFusionMobile
  • 14,812
  • 25
  • 102
  • 140

1 Answers1

1

hm, maybe you can just copy the relevant things out of Androids Source-Code? You will need at least:

If it is not working out of the Box, consider to take it as a 'Code-Design-Guideline'

Rafael T
  • 15,401
  • 15
  • 83
  • 144
  • I thought about doing this, but it's kindof a last resort. I'd prefer to use a more standard java approach if one exists. – CodeFusionMobile May 22 '12 at 13:28
  • I know, its not the ideal solution... i just googled and found this: http://code.google.com/p/simple-mq/ Maybe it helps you a little – Rafael T May 22 '12 at 13:31
  • Got it to work. Implemented a stripped down version because a lot of the features tied in directly to the android platform and had to be removed. – CodeFusionMobile May 22 '12 at 15:20
  • @CodeFusionMobile can you share your strip down version with me? I need it too. – jeevs Apr 01 '14 at 18:47