为什么这个Thread会冻结UI

时间:2014-03-24 15:26:12

标签: android multithreading

在我的代码中,只要选中ToggleButton,我就必须发送消息。为了防止UI线程冻结,我将操作放在一个单独的线程中。

我的问题是,它仍然冻结,但我不知道为什么

这是相关代码:

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;
            }
        }

    }

}

修改 这是解决问题的方法:

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();
        }
    }

};

1 个答案:

答案 0 :(得分:3)

 Handler lightHandler = new Handler();

创建处理程序时,您的线程尚未启动。它正在被创造。因此,根据Handler&#39; s default constructor documentation,此处理程序与当前线程的Looper相关联&#34; ...这是当前的主要(UI)线程。所以你在主线程上发布你的消息。

您不需要Handler发布您的可运行邮件。你可以:

  1. 创建一个主题并在run()方法中指定它的操作 或
  2. 使用Thread(Runnable)构造函数将Runnable传递给将在您的主题中执行的线程
  3. 以下是有关Threads的基本文章:

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