Android Gingerbread: невозможно создать обработчик внутри потока, который не вызвал Looper.prepare()

У меня есть такой код:

final Context context = this;
Timer timer = new Timer();
timer.schedule(new TimerTask()
{
    @Override
    public void run()
    {
        new CheckMessageTask(context).execute(); //ERROR
    }
}, 2500, 10 * 60 * 1000); //Every 10 Minutes

Таймер должен выполнять CheckMessageTask каждые 10 минут. Проблема в том, что появляется эта ошибка:

E/AndroidRuntime: FATAL EXCEPTION: Timer-0
    java.lang.ExceptionInInitializerError
    at -package-CheckMessageService$1.run(CheckMessageService.java:138)
    at java.util.Timer$TimerImpl.run(Timer.java:284)
    Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    at android.os.Handler.<init>(Handler.java:121)
    at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
    at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
    at android.os.AsyncTask.<clinit>(AsyncTask.java:152)
    ... 2 more

CheckMessageTask расширяет Asynctask и не запускает код пользовательского интерфейса, поэтому причина не в этом. Код отлично работает на Android Jelly Bean 4.1.2, но не на Android Gingerbread. Как я могу это исправить?


person Trojaner    schedule 11.06.2013    source источник
comment
Проверьте это: stackoverflow.com/a/13267931/1468093   -  person Kamran Ahmed    schedule 16.09.2013


Ответы (2)


Ваша задача таймера выполняется в другом потоке. Вы должны загрузить asynctask в основной поток пользовательского интерфейса

Проверьте ссылку ниже в разделе Правила создания потоков.

http://developer.android.com/reference/android/os/AsyncTask.html

Класс AsyncTask должен быть загружен в UI thread. Это делается автоматически с JELLY_BEAN.

Итак, в Jelly bean это работает нормально.

person Raghunandan    schedule 11.06.2013
comment
во-первых, зачем вам асинтаск, если служба работает в фоновом режиме? - person Raghunandan; 11.06.2013
comment
потому что он подключается к Интернету, разве это не вызывает исключение, если он не использует асинхронную задачу? - person Trojaner; 11.06.2013

вы не можете выполнять Asynctask не из потока пользовательского интерфейса, что является случаем при использовании таймера

person pskink    schedule 11.06.2013
comment
потому что в 4.1.2 это делается автоматически. Класс AsyncTask должен быть загружен в поток пользовательского интерфейса. Это done automatically от JELLY_BEAN. - person Raghunandan; 11.06.2013
comment
понятия не имею, см. developer.android.com/reference/android/os/AsyncTask .html раздел Правила многопоточности - person pskink; 11.06.2013
comment
@Trojaner, можешь объяснить, зачем тебе таймер? Я думаю, тебе нужно переосмыслить свой подход - person Raghunandan; 11.06.2013
comment
Код выполняется службой, поэтому поток пользовательского интерфейса отсутствует. @Raghunandan, как мне это сделать? - person Trojaner; 11.06.2013
comment
@Trojaner, я предлагаю вам переосмыслить свой дизайн. служба работает в фоновом режиме. в службе у вас есть таймер, и вы загружаете асинтаск внутри таймера. вы должны изменить свой подход. вам нужно параллельное выполнение? - person Raghunandan; 11.06.2013