Reputation: 473
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
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:
run()
method
orRunnable
to your thread that will be executed in your thread using the Thread(Runnable)
constructorHere are the basic articles about Threads
:
Upvotes: 4