CountDownTimer: «Невозможно создать обработчик внутри потока, который не вызвал Looper.prepare ()» - PullRequest
3 голосов
/ 24 октября 2010

Мне известна общая проблема «Не удается создать обработчик внутри потока, который не вызвал Looper.prepare ()», но я изо всех сил пытаюсь понять, как он применяется в этом случае.

Я пытаюсь создать новый CountDownTimer в потоке, не являющемся пользовательским интерфейсом, который, как мне кажется, является причиной этой ошибки, но я не совсем понимаю, почему таймер должен использоваться в основном потоке,Из того, что я вижу, похоже, что у него есть обработчик обратного вызова, который должен выполняться в потоке с петлителем, которого у потока без пользовательского интерфейса по умолчанию нет.Кажется, у меня есть следующие варианты: 1) сделать этот не-пользовательский поток с Looper или 2) создать какой-то странный метод в моем пользовательском потоке, который может создать этот таймер, оба кажутся мне глупыми.Может ли кто-нибудь помочь мне понять последствия?

Кроме того, кто-нибудь знает какие-либо полезные ссылки, которые проливают свет на Looper и MessageQueue?Я не понимаю их хорошо, как я уверен, я показал.Спасибо!

Ответы [ 2 ]

3 голосов
/ 24 октября 2010

Таймер не должен быть в потоке пользовательского интерфейса. Но я думаю, вы обновляете пользовательский интерфейс, чтобы отобразить счетчик обратного отсчета в этом потоке. Ю не может этого сделать.

Используйте asynctask и обновите пользовательский интерфейс в onProgressUpdate

2 голосов
/ 10 сентября 2014

Экземпляр CountDownTimer должен быть создан в потоке пользовательского интерфейса.

Если у вас был объект пользовательского класса:

public class MyTimer extends CountDownTimer{
    public MyTimer(...){
         super(duration,interval);
    }
    //... other code ...//
}

Конструкция объекта должна выполняться в потоке пользовательского интерфейса

MyTimer mTimer = new MyTimer(...);   //can throw RuntimeException
                                    // with Looper.prepare() issue if
                                    // caller isn't UI thread

Если несколько потоков создают и уничтожают таймер, убедитесь, что он создан в потоке пользовательского интерфейса, выполнив что-то вроде этого:

MyActivity.runOnUiThread( new Runnable(){
     public void run(){
          mTimer = new MyTimer(...);
     }
});

, но обратите внимание на то, как нужен вышеуказанный сегмент кодассылка на вашу активность и переменную члена класса mTimer

...