Прервать поток во время цикла, используя сообщение из пользовательского интерфейса

Я уверен, что решение моей проблемы будет одним из тех «духовных» моментов, но я застрял, поэтому любые полезные советы будут с благодарностью получены.

Проблема: у меня есть пользовательский интерфейс с фоновым потоком. В пользовательском интерфейсе есть кнопка запуска/остановки для запуска, а затем остановки процесса в потоке. Это достигается с помощью сообщений от пользовательского интерфейса к обработчику сообщений в потоке, заключенном в цикл. Процесс потока находится в цикле while, зависящем от логического значения, установленного обработчиком сообщений потока. Однако после запуска дальнейшие сообщения не обрабатываются, и цикл продолжается до бесконечности.

private class MyThread extends Thread{
    public void run() {
      Looper.prepare();
          MyThreadChildHandler = new Handler() {
              public void handleMessage(Message msg) {
                  switch(msg.arg1) {
                 case START:
                          boolLoop = true;
                          doWhileLoop();
                     case STOP:
                          boolLoop = false;
                     }
          };
      Looper.loop();
    }

    private void doWhileLoop(){
        while (boolLoop = true){
            stuff.do
        }
        finish.do
    }

}

У меня есть сообщение logcat в сообщении STOP из пользовательского интерфейса, и оно срабатывает, но поток никогда не поднимает его, потому что он застрял в цикле while, а обработчик сообщений не получает просмотра.

Есть ли способ позволить обработчику потока проверять сообщения из цикла while в разных точках? Или есть другой способ заставить непрерывный цикл while на основе потока запускаться и останавливаться на основе сообщений из пользовательского интерфейса?

Ура Энди


person Andy Lee    schedule 09.04.2013    source источник


Ответы (1)


Изменять:

  while (boolLoop = true){
            stuff.do
        }

to:

  while (boolLoop == true){
            stuff.do
        }

или предпочтительно

  while (booloop){
          stuff.do
        }

Вам нужно проверять равенство (==), а не присваивать (=).

Еще одна вещь: вам не нужен объект петлителя. Просто управляйте им с помощью цикла while. Я бы сделал это так:

Я хотел бы, чтобы поток выполнял свой процесс бесконечно, пока не истечет время ожидания или сообщение от обработчика, который управляет этим потоком, не остановит выполнение этого потока через переменную флага, которая является общей для двух классов, таких как Activity и Thread. Где состояние активности управляет потоком. Например, скажем, приложение переходит в фоновый режим, тогда вы должны установить флаг выполнения в false, чтобы оно остановилось. Ваша Looper казнь не нужна. Кроме того, сообщения будут передаваться через обработчик.

person JoxTraex    schedule 09.04.2013
comment
Это хорошая рекомендация, но я не уверен, что она сработает. Настоящая проблема OP, я думаю, заключается в том, что handleMessage никогда не возвращается из сообщения START, поэтому зацикливатель никогда не обрабатывает следующее сообщение. - person Ted Hopp; 10.04.2013
comment
Спасибо за супер быстрый ответ, ребята. - person Andy Lee; 10.04.2013
comment
JoxTraex, =vs== была просто опечаткой в ​​сокращении моего кода. Я пытался избежать глобальных переменных, чтобы обеспечить управление пользовательским интерфейсом/потоком и вместо этого использовать обмен сообщениями. Но это привело меня в мою нынешнюю кроличью нору. Может быть, цикл не нужен, так как мне действительно не нужно ставить в очередь много сообщений, но мне все еще нужен способ прервать цикл while на основе сообщения из пользовательского интерфейса. - person Andy Lee; 10.04.2013
comment
На самом деле это не кроличья нора, но это кроличья нора, судя по тому, как вы к ней приближаетесь. Мой подход решает эту проблему, и обойти глобальную переменную на самом деле невозможно. Или другой подход должен заключаться в том, чтобы использовать методологию Activity и Service и иметь Activity, управляющий этой службой через привязки. Они могут передавать сообщения напрямую друг другу. - person JoxTraex; 10.04.2013
comment
Тед Хоуп, да, это проблема. Я хочу продолжать stuff.do(ing) до тех пор, пока из пользовательского интерфейса не будет сделан запрос на остановку. Затем Finish.do и, наконец, выйдите из подпрограммы doWhileLoop(). Поток застревает в цикле while и никогда не обрабатывает входящее сообщение. Можете ли вы придумать другой способ достичь моей цели. Та. - person Andy Lee; 10.04.2013
comment
Посмотрите методологию, которую я упомянул о привязках службы и активности. Это должно справиться с этим. - person JoxTraex; 10.04.2013
comment
Спасибо Джокс Трекс. Раньше у меня это работало с использованием глобального флага, но я пытался провести рефакторинг, используя подход обмена потоковыми сообщениями, поскольку предполагается, что он «превосходит» глобальные переменные, которые люди, похоже, не одобряют. Очевидно, что мои проблемы с привязкой к этому в какой-то степени являются аргументом в пользу глобалов. Думаю, я мог бы воспользоваться вашим советом и вернуться к этому подходу. Ваше здоровье. - person Andy Lee; 10.04.2013