Android开发Sleep与Message并用无效解决方案
问题描述
2022/8/24 21:54特此记录,历经两天解决此问题
为了完成比赛题目要求,我在代码中写了当读取到已登记epc会触发电动推杆缩回,等完全缩回再过10秒伸出,这一步骤是合理运行的,但是因要更新界面UI,而当前在子线程,故采用Handler-Message的方式发送消息,当UI主线程接收到消息时更新界面
为了省事,我将此操作写在了同一作用域Thread.sleep前后,当代码执行到这里的时候并没有达到预期的效果,事时是Message等sleep执行完后一起触发了,所以得出结论Message不能在同一作用域用两次,如果用的话不会报错,只是效果会得不尝失
原代码
public void RfidCtrl(){
new Thread(new Runnable() {
@Override
public void run() {
while (true){
try {
Thread.sleep(5000);
rfid.readSingleEpc(new SingleEpcListener() {
@Override
public void onVal(String s) {
try {
Log.e("RfidEPC", s);
tempEpcInfo = s;
if(!currentEpcInfo.equals(tempEpcInfo)){
if(!tempEpcInfo.equals(rfidEpcInfo)) {
textToSpeech.speak("信息未登记", TextToSpeech.QUEUE_ADD, null);
Message msg = new Message();
msg.what = 0;
handler.sendMessage(msg);
}
else{
textToSpeech.speak("你好,请通过", TextToSpeech.QUEUE_ADD, null);
Message msg = new Message();
msg.what = 1;
handler.sendMessage(msg);
modbus4150.ctrlRelay(1, true, null);
modbus4150.ctrlRelay(0, false, null);
modbus4150.ctrlRelay(2, false, null);
modbus4150.ctrlRelay(5, false, null);
modbus4150.ctrlRelay(6, true, null);
Log.e("Thread", Thread.currentThread().getName());
Thread.sleep(17000);
/*for(int i = 0; i < 17000; i++){
Thread.sleep(1);
}*/
Log.e("Thread2", Thread.currentThread().getName());
modbus4150.ctrlRelay(5, true, null);
modbus4150.ctrlRelay(6, false, null);
modbus4150.ctrlRelay(1, false, null);
modbus4150.ctrlRelay(0, true, null);
modbus4150.ctrlRelay(2, false, null);
Message msg_2 = new Message();
msg_2.what = 0;
handler.sendMessage(msg_2);
}
currentEpcInfo = tempEpcInfo;
}
}
catch (Exception e){
}
}
@Override
public void onFail(Exception e) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
更改后
public void RfidCtrl(){
new Thread(new Runnable() {
@Override
public void run() {
while (true){
try {
if(isTurn) {
Thread.sleep(17000);
modbus4150.ctrlRelay(5, true, null);
modbus4150.ctrlRelay(6, false, null);
modbus4150.ctrlRelay(1, false, null);
modbus4150.ctrlRelay(0, true, null);
modbus4150.ctrlRelay(2, false, null);
Message msg_2 = new Message();
msg_2.what = 0;
handler.sendMessage(msg_2);
isTurn = false;
currentEpcInfo = "null";
}
else Thread.sleep(3000);
rfid.readSingleEpc(new SingleEpcListener() {
@Override
public void onVal(String s) {
try {
Log.e("RfidEPC", s);
tempEpcInfo = s;
if(!currentEpcInfo.equals(tempEpcInfo)){
if(!tempEpcInfo.equals(rfidEpcInfo)) {
textToSpeech.speak("信息未登记", TextToSpeech.QUEUE_ADD, null);
Message msg = new Message();
msg.what = 0;
handler.sendMessage(msg);
}
else{
textToSpeech.speak("你好,请通过", TextToSpeech.QUEUE_ADD, null);
Message msg = new Message();
msg.what = 1;
handler.sendMessage(msg);
modbus4150.ctrlRelay(1, true, null);
modbus4150.ctrlRelay(0, false, null);
modbus4150.ctrlRelay(2, false, null);
modbus4150.ctrlRelay(5, false, null);
modbus4150.ctrlRelay(6, true, null);
Log.e("Thread", Thread.currentThread().getName());
//Thread.sleep(17000);
Log.e("Thread2", Thread.currentThread().getName());
isTurn = true;
}
currentEpcInfo = tempEpcInfo;
}
}
catch (Exception e){
}
}
@Override
public void onFail(Exception e) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
Handler消息处理模块
handler = new Handler(message -> {
switch (message.what){
case 0:
Toast.makeText(MainActivity.this, "Close", Toast.LENGTH_SHORT).show();
m_raycast.setImageResource(R.drawable.pic_traffic_light_red);
gate.setImageResource(R.drawable.pic_parking_rod_closed);
break;
case 1:
Toast.makeText(MainActivity.this, "Turn", Toast.LENGTH_SHORT).show();
m_raycast.setImageResource(R.drawable.pic_traffic_light_green);
gate.setImageResource(R.drawable.pic_parking_rod_open); //修改UI界面控件属性
break;
}
return true;
});
发送消息模块
Message msg = new Message();
msg.what = 0;
handler.sendMessage(msg);