0

I create a thread to listening the input stream of the serial port. And when there is input data coming, I want to send a message to UI thread.

Before doing my task, I try to send message from the thread with interval 5000 ms, and send a message to UI thread and Toast it. From the log, I know that the thread is created and running succefully, but the number is not toasted in the UI thread.

I think it may be due to fail to send a message from the thread to UI thread, or fail to handle the message in the MessageQueue of UI thread.

What's wrong with my code? Many thanks!

MainActivity.java:

public class MainActivity extends Activity {
    ...
    @Override
    protected void onCreate(Bundle savedInstancesState) {
        ...
        setMessageProcessor();
        SerialPortListener.start();
    }        

    private void setMessageProcessor() {
        new Handler(Looper.getMainLooper()) {
            public void handleMessage(Message msg) {
                Toast.makeText(MainActivity.this,
                    "Message: " + msg.obj.toString(),
                    Toast.LENGTH_SHORT).show();
            }
        };
    }
}

SerialPortListener.java:

public class SerialPortListener {
    ...
    private static int testNumber = 1;
    public static void start() {
        ...
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    Message msg = new Message();
                    msg.obj = testNumber++;
                    new Handler(Looper.getMainLooper()).sendMessage(msg);
                    Log.i("TEST", "TEST);
                    try {
                        Thread.sleep(5000);
                    } catche(Exception e) {
                        ...
                    }
                }
            }
        });
        thread.start();
    }
}
Nestarneal
  • 205
  • 1
  • 2
  • 12

1 Answers1

3

It's because you are creating a second Handler bound to the main thread from within your "reader thread". Don't use an anonymous object for the handler in the main thread, make it a member field. Then in your reader thread, send the Message to that specific Handler:

private void setMessageProcessor() {
    mHandler = new Handler() {
        ...
    }
}

public class SerialPortListener {
...
private static int testNumber = 1;
public static void start() {
    ...
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                Message msg = mHandler.obtainMessage();
                msg.obj = testNumber++;
                msg.sendToTarget();
                Log.i("TEST", "TEST);
                ...
        }
    }
}
Larry Schiefer
  • 15,687
  • 2
  • 27
  • 33
  • So, it means I need declare ```public static Handler``` in my main thread? Is it possible to declare it with ```private Handler```? – Nestarneal Mar 29 '17 at 10:46
  • As long as `SerialPortListener` is an inner class of your `Activity`, then it's fine. A better approach (since I now see you had them in separate files) would be to pass the `Handler` to your `SerialPortListener` when you create it. – Larry Schiefer Mar 29 '17 at 10:51