防止UI在处理数据时冻结

本文关键字:冻结 数据 处理 UI 防止 | 更新日期: 2023-09-27 17:50:32

我在BluetoothChat(我相信它在bot Java和MonoForAndroid上的代码相同)示例应用程序中遇到了一些问题。我已经使用蓝牙模块将我的Android连接到微控制器。在发送消息(只是原始字节到微控制器)的情况下,它工作得很好!

微控制器流一个恒定的串行消息,我想读取该数据。在BluetoothChat.cs应用程序中有一个名为MyHandler的类,其代码块如下:

    case MESSAGE_READ:
        byte[] readBuf = (byte[])msg.Obj;
        // construct a string from the valid bytes in the buffer
        var readMessage = new Java.Lang.String (readBuf, 0, msg.Arg1);
        bluetoothChat.conversationArrayAdapter.Add(
        bluetoothChat.connectedDeviceName + ":  " + readMessage);
        break;
所以我需要做的是处理传入的原始数据,然后改变一些按钮的颜色,所以我对上面的代码做了以下更改:
case MESSAGE_READ:
    byte[] readBuf = (byte[])msg.Obj;
         //I have just added this code and it blocks the UI
         bluetoothChat.ProcessIncomingData(readBuff);
    break;

BluetootChat活动中,我有这个方法:

    public void ProcessIncomingData(byte[] readBuf)
    {
        if (_logBox != null)
        {
            _logBox.Text += "'r'n"; //TextView
            foreach (var b in readBuf)
            {
                _logBox.Text += (uint)b + " "; //Show the bytes as int value
            }
        }
    }

但不幸的是,我所做的改变停止了UI和应用程序崩溃后不久。

有什么办法可以在不冻结UI的情况下整洁地完成这个任务吗?

防止UI在处理数据时冻结

您需要将工作交给后台线程,以便保持UI线程空闲以响应输入。我写了一篇文章,概述了一些不同的方法,你可以做后台线程:使用后台线程在Mono Android应用程序

处理后台线程时要注意的一点是,如果你想对UI做任何改变,你必须切换回UI线程。您可以使用RunOnUiThread()方法来完成此操作。

为将要发生的进程创建一个新线程

public static void threadProcess()
{
    Thread thread = new Thread()
            {
                public void run()
                {
                // Process that will run in the thread
                }
            };
            thread.start();
}