首页 新闻 会员 周边 捐助

安卓ui同步线程阻塞问题

0
悬赏园豆:5 [已解决问题] 解决于 2024-09-24 15:06

public void onClick(View view) {
if (view.getId() ==R.id.BTN_O2_RESET) {
Log.i("onclick", "BTN_O2_N2");
//提示信息
State_ALL_ZERO.setText("正在调零");
State_ALL_ZERO.invalidate();
SendCommand.delay(4000);//延时

        {语句体,执行发送串口命令}

        SendCommand.delay(4000);//延时
 //提示信息
       State_ALL_ZERO.setText("调零结束");

        State_ALL_ZERO.invalidate();

}

以上为一button按钮单击事件,点击后需求是在text 显示正在调零,然后执行完发送串口命令后,在text中显示调零结束。
但实际执行时,却不显示正在调零,只显示调零结束。查过资料是ui同步线程阻塞问题,请高手帮忙修改,指点一下,谢谢!

tea2007的主页 tea2007 | 初学一级 | 园豆:7
提问于:2024-09-23 17:23
< >
分享
最佳答案
0

不要在ui线程里执行delay,单独开个线程,或者用sendMessageDelayed一步一步完成操作.

收获园豆:5
www378660084 | 小虾三级 |园豆:1143 | 2024-09-24 10:38
其他回答(1)
0

public void onClick(View view) {
if (view.getId() ==R.id.BTN_O2_RESET) {
Log.i("onclick", "BTN_O2_N2");
//提示信息
State_ALL_ZERO.setText("正在调零");
State_ALL_ZERO.invalidate();
SendCommand.delay(4000);//延时
}

    SendCommand.delay(4000);//延时

}
以上语句中当符合if条件时,先更新State_ALL_ZERO.setText("正在调零");
然后再执行语句体,请参考下面例子修改上面代码。
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
// 在主线程中更新UI
}
});

//-----------------------------------------------------------------------------------------
在您的代码中,您希望在点击按钮时更新UI(即设置State_ALL_ZERO的文本),然后执行某些操作(可能是发送串口命令),并在这些操作之后再次延时。但是,您的SendCommand.delay(4000);调用似乎并不符合Android的标准做法,因为SendCommand很可能不是一个Android类,也没有标准的delay方法。在Android中,我们通常使用Handler或View.postDelayed来延迟执行代码。

下面是一个修改后的示例,它使用Handler来更新UI,并在更新UI后执行一些操作(比如发送串口命令),然后再次延时。但是,请注意,由于Android的UI更新是自动的,所以通常不需要调用invalidate()来强制更新UI(除非您正在做自定义的绘图),并且这里我们没有直接展示如何发送串口命令,因为这通常涉及到硬件通信或第三方库。

java
public void onClick(View view) {
if (view.getId() == R.id.BTN_O2_RESET) {
Log.i("onclick", "BTN_O2_RESET clicked");

    // 更新UI  
    final TextView stateAllZero = findViewById(R.id.State_ALL_ZERO); // 假设这是您的TextView的ID  
    stateAllZero.setText("正在调零");  

    // 使用Handler在主线程中执行操作(如果操作不在主线程中,则不需要这一步)  
    // 但对于发送串口命令,您可能需要在一个单独的线程中执行  
    Handler handler = new Handler(Looper.getMainLooper());  
    handler.post(new Runnable() {  
        @Override  
        public void run() {  
            // 这里通常是执行不需要延时的UI更新  
            // 但在这个场景中,我们已经在之前更新了UI  

            // 假设sendSerialCommand是一个发送串口命令的方法  
            // 注意:如果这个方法涉及耗时操作或需要访问UI,请确保它在正确的线程中执行  
            sendSerialCommand(); // 执行发送串口命令的操作  

            // 延时后再次执行某些操作(如果需要的话)  
            handler.postDelayed(new Runnable() {  
                @Override  
                public void run() {  
                    // 这里是延时后执行的操作  
                    // 例如,更新UI或执行其他任务  
                    stateAllZero.setText("调零完成");  
                }  
            }, 4000); // 延时4000毫秒(4秒)  
        }  
    });  

    // 注意:上面的postDelayed已经包含了延时逻辑,所以这里不需要再调用delay  
}  

}

// 假设的发送串口命令的方法(需要您自己实现)
private void sendSerialCommand() {
// 在这里实现发送串口命令的逻辑
// 注意:这可能需要在一个单独的线程中执行,以避免阻塞UI线程
}
请注意,上面的代码示例中,我假设sendSerialCommand()方法是一个您已经实现或需要实现的方法来发送串口命令。如果这个方法包含耗时的I/O操作,请确保它在非UI线程中执行,以避免阻塞UI。如果它只是简单地调用某个库函数来发送命令,并且这个库已经处理了线程问题,那么您可以直接在UI线程中调用它(如上所示)。但是,如果库没有处理线程问题,您可能需要使用AsyncTask、HandlerThread、ExecutorService或Kotlin的协程来在后台线程中执行它。

tea2007 | 园豆:7 (初学一级) | 2024-09-24 15:06
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册