在我的代码中,只要我的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();
}
}
};
我建议你查一下有关使用Java多线程的一些教程,你在那里有几次失误。例如,扩展Thread并在其内部创建一个Runnable是多余的,一个线程已经是一个Runnable。 – m0skit0
你可能会说出其中的一些,所以它更容易做研究? – Fraggles
对不起,这不是一个学习的地方,但要提出具体问题。你甚至不应该尝试写多线程代码,而不必先阅读它。我可以指向[Oracle的官方教程](http://docs.oracle.com/javase/tutorial/essential/concurrency/),它们是一个很好的开始。 – m0skit0