2010-10-23 5 views
3

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

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

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

ответ

3

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

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

+0

Я не считаю, что это так. Я прокомментировал весь код внутри анонимного класса, так что все, что он вызывает, вызывает супер в конструкторе, но я все равно получаю ту же ошибку. Это потому, что у CountDownTimer есть метод обратного вызова, когда он закончен, и это должно быть «запущено» петлером? Это путаница, которую я надеюсь прояснить. Мы даже можем отвлечь проблему от моей конкретной проблемы - я просто пытаюсь понять, как все это сочетается. Спасибо. – skaz

+0

О, я думаю, что неправильно понял ваш вопрос. Могу ли я спросить, почему вы используете «CountdownTimer» в потоке nonUI? Я думаю, что точка 'CountdownTimer' должна иметь возможность легко обновлять поток пользовательского интерфейса. Похоже, что 'onTick()' и 'onFinish()' должны запускаться в потоке пользовательского интерфейса. Почему бы просто не использовать обычный таймер java? – Falmarri

+0

Думаю, я могу использовать обычный таймер. Независимо от того, почему CountDownTimer бомбит в конструкторе, если я не буду обновлять пользовательский интерфейс? – skaz

2

Экземпляр 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

Смежные вопросы

 Смежные вопросы