How to implement Android message handler pattern in standard Java?

人走茶凉 提交于 2019-12-12 10:04:00

问题


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?


回答1:


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

  • Looper
  • Handler
  • Message
  • MessageQueue

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



来源:https://stackoverflow.com/questions/10702622/how-to-implement-android-message-handler-pattern-in-standard-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!