Fraggles
Fraggles

Reputation: 473

Why does this Thread freeze the UI

In my code I have to send a message as long as my ToggleButton is checked. To prevent the UI Thread from freezing, I put the action in a seperate Thread.

My Problem is, that it still freezes, but I don't know why

This is the relevant code:

private ToggleButton.OnClickListener lightMirrorOnClickListener = new ToggleButton.OnClickListener() {

    @Override
    public void onClick(View v) {
        if (lightMirrorBtn.isChecked()) {
            lightThread = new LightThread();
            lightThread.start();
        } else if(!lightMirrorBtn.isChecked()) {
            lightThread.interrupt();
        }
    }

};

class LightThread extends Thread {

    Handler lightHandler = new Handler();

    Runnable light = new Runnable() {
        public void run() {

            while (lightMirrorBtn.isChecked()) {
                lightTxMsg.frameFormat = ConstantList.STANDARD_FRAME;
                lightTxMsg.frameType = ConstantList.DATA_FRAME;
                lightTxMsg.dataLength = (byte) 8;
                lightTxMsg.messageID = 0x3C1;
                int[] messageArray = AMBI_LIGHT;
                for (int i = 0; i < lightTxMsg.dataLength; i++) {
                    lightTxMsg.data[i] = messageArray[i];
                }

                returnCode = demoController.transmitMessage(lightTxMsg,
                        ConstantList.BINARY_FORMAT);    
            }
        }
    };

    public void run() {
        while (!isInterrupted()) {
            try {
                Thread.sleep(60);
                lightHandler.post(light);

            } catch (InterruptedException e) {
                break;
            }
        }

    }

}

EDIT: This was the solution for the problem:

private ToggleButton.OnCheckedChangeListener lightMirrorOnClickListener = new ToggleButton.OnCheckedChangeListener() {

    @Override
    public void onCheckedChanged(CompoundButton buttonView,
            boolean isChecked) {
        if (isChecked == true) {
            new Thread(new Runnable() {
                public void run() {
                    lightTxMsg.frameFormat = ConstantList.STANDARD_FRAME;
                    lightTxMsg.frameType = ConstantList.DATA_FRAME;
                    lightTxMsg.dataLength = (byte) 8;
                    lightTxMsg.messageID = 0x3C1;
                    int[] messageArray = AMBI_LIGHT_ON;
                    for (int i = 0; i < lightTxMsg.dataLength; i++) {
                        lightTxMsg.data[i] = messageArray[i];
                    }

                    returnCode = demoController.transmitMessage(lightTxMsg,
                            ConstantList.BINARY_FORMAT);
                }
            }).start();

        }  else if (!isChecked) {
            new Thread(new Runnable() {
                public void run() {
                    lightTxMsg.frameFormat = ConstantList.STANDARD_FRAME;
                    lightTxMsg.frameType = ConstantList.DATA_FRAME;
                    lightTxMsg.dataLength = (byte) 8;
                    lightTxMsg.messageID = 0x3C1;
                    int[] messageArray = AMBI_LIGHT_OFF;
                    for (int i = 0; i < lightTxMsg.dataLength; i++) {
                        lightTxMsg.data[i] = messageArray[i];
                    }

                    returnCode = demoController.transmitMessage(lightTxMsg,
                            ConstantList.BINARY_FORMAT);
                }
            }).start();
        }
    }

};

Upvotes: 2

Views: 4474

Answers (1)

stan0
stan0

Reputation: 11817

 Handler lightHandler = new Handler();

When you create your handler your thread has not yet started. It is just being created. So, according to the Handler's default constructor documentation this handler is associated "with the Looper for the current thread" ... which is currently the main(UI) thread. So you post your messages on the main thread.

You don't need a Handler to post your runnable on. You can either:

  1. Create a Thread and specify it's actions in the run() method or
  2. Pass a Runnable to your thread that will be executed in your thread using the Thread(Runnable) constructor

Here are the basic articles about Threads:

  1. Processes and threads
  2. Keeping your app responsive
  3. Specifying the Code to Run on a Thread

Upvotes: 4

Related Questions