System.Threading: Запуск в Java.Lang.RuntimeException: Не удается создать обработчик внутри потока, который не вызвал Looper.prepare () - PullRequest
0 голосов
/ 09 января 2019

В моем Xamarin.Android-приложении при открытии специальной страницы (действия) при создании отображается таблица. ListAdapter определяет определенные поля в этой таблице. У меня есть функция, которая дает мне внешний int. 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 ()

Может кто-нибудь сказать мне, в чем проблема / как это исправить?

С наилучшими пожеланиями

Edit: метод 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 голосов
/ 09 января 2019

Делай, что говорит, и звони 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...