c# Android Xamarin-使用 TextView.Text 与 ElapsedEventHandler 时崩溃

标签: Android C#
发布时间: 2017/3/4 6:14:31
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

当我调用我的应用程序崩溃 Print 功能而我使用的 System.Timers.ElapsedEventHandler(checkForMessage)

我叫 Print 功能在其他上下文中并没有任何问题。

using System;
using Android.App;
using Android.Widget;
using Android.OS;

namespace Ev3BtCom
{
    [Activity(Label = "Ev3BtCom", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        Ev3Messaging _ev3Messaging = new Ev3Messaging();

        bool isParsing = true;
        TextView infosLabel;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            SetContentView (Resource.Layout.Main);

            ...
            infosLabel = FindViewById<TextView>(Resource.Id.Infos);

            _ev3Messaging = new Ev3Messaging();


            System.Timers.Timer checkForTime = new System.Timers.Timer(500);
            checkForTime.Elapsed += new System.Timers.ElapsedEventHandler(checkForMessage);
            checkForTime.Enabled = true;



            connectBut.Click += async (object sender, EventArgs e) =>
            {
                bool error = false;
                try
                {
                    await _ev3Messaging.Connect(brickNameET.Text);
                }
                catch (Exception ex)
                {
                    Print(ex.Message);
                    error = true;
                }
                if(!error)
                {
                    Print("Connected");
                    isParsing = false;
                }
            };

            ...//Many use of the print function in the same context WITHOUT CRASH
        }

        async void checkForMessage(object source, System.Timers.ElapsedEventArgs e)
        {
            if (!isParsing)
            {
                isParsing = true;
                byte[] datas = new byte[0];
                try
                {
                    datas = await _ev3Messaging.ReceiveText();
                }catch (Exception ex)
                {
                    await _ev3Messaging.SendText("Text", ex.Message);
                    Print(ex.Message);   // MAKES APP CRASH
                }
                if (datas.Length != 0)
                {
                    string printedText = "Received: ";
                    foreach (byte b in datas)
                        printedText += (int)b + ",";
                    Print(printedText);    // MAKES APP CRASH
                    await _ev3Messaging.SendText("Text", printedText);
                }
                Print("Test");   // MAKES APP CRASH
                isParsing = false;
            }
        }

        void Print(string text)
        {
            infosLabel.Text += text + "\n"; // When I remove this line, there is no more crash
        }
    }
}

解决方法 1:

是 Timer.Elapsed 事件总是排队在线程池线程上执行,因此您需要确保您更新 UI 控件在 UI 线程上。要实现,你可以使用 RunOnUiThread 方法如下所示︰

void Print(string text)
{
    RunOnUiThread(() => infosLabel.Text += text + "\n");
}
赞助商