System.Threading:遇到Java.Lang.RuntimeException:无法在尚未调用Looper.prepare()的线程内创建处理程序

时间:2019-01-09 14:57:22

标签: c# android xamarin.android refresh android-runonuithread

在我的Xamarin.Android-App中,打开特殊页面(活动)时,在create上显示一个表。 ListAdapter定义该表中的某些字段。我有一个函数,可以获取外部整数。 int是该表中显示的其他数据。但是此函数仅被调用一次(创建时)。我想在运行时动态检测此接收到的int是否已更改,如果是,也要更改表中int的显示。

请参阅我的以下代码:

ListAdapter.cs:

var thread = new Thread(() => MethodToRun());
thread.Start();

[...]

void MethodToRun()
{
    while (true)
    {
        Thread.Sleep(1000);
        var a = new Activity();
        a.RunOnUiThread(() => {

            int number = Get_Number();
            if (number == 1)
            {
                v.FindViewById<TextView>(Resource.Id.textView).Text = "1";
            }
            if (number != 1)
            {
                v.FindViewById<TextView>(Resource.Id.textView).Text = "Not 1 anymore";
            }
        });
    }
}

不幸的是,我在行var a = new Activity();

时遇到运行时错误
  

Java.Lang.RuntimeException:无法在该线程内部创建处理程序   尚未调用Looper.prepare()

谁能告诉我问题出在哪里/如何解决?

最诚挚的问候

编辑:Get_Number()方法如下所示:

private int Get_Number(Geraet geraet)
{
    var request = HttpWebRequest.Create(string.Format(Constants.WebservicePath, Serverip, Constants.WebservicePort, geraet.Ip));
    request.ContentType = "application/json";
    request.Method = "GET";

    using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
    {
        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        {
            var content = reader.ReadToEnd();
            var result = System.Text.RegularExpressions.Regex.Replace(content, @"[^0-9]", "");

            if (result == string.Empty)
            {
                return -2;
            }
            else
            {
                return Int32.Parse(result);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

按照提示说,然后致电Looper.prepare()

void MethodToRun() {
    Looper.prepare();

    //...
}

但是,您还有其他问题。您不能自己创建Activity的新实例。如果要在主线程上运行某些内容,请创建一个新的处理程序:

var handler = new Handler(Looper.GetMainLooper());

然后您可以发布它:

handler.Post(() => {
    int number = Get_Number();

    //...
}

但是,如果您想在主线程上运行重复动作,那么您要做的就是创建要避免的处理程序。

尝试这样的方法:

var handler = new Handler(Looper.GetMainLooper());

Runnable actions = new Runnable() => {
    int number = Get_Number(); //this needs to be async

    handler.Post(() => {
        TextView text = v.FindViewById(Resource.Id.textView);

        text.Text = number == 1 ? "1" : "Not 1 anymore";

        PostAction();
    }
}; //the syntax for this might be wrong, since I don't know C#

void PostAction() {
    handler.postDelayed(() => {
        new Thread(actions).start();
    }, 1000);
}

这样,您只需调用一次PostAction()即可使事情继续进行,然后它将不断循环您的逻辑。

如果要停止循环:

handler.RemoveCallbacks(actions);