Ошибка вызова тоста из Сервиса Android

Возможный дубликат:
Android Toast запущен из Сервиса отображается только один раз

Я использую Сервис Android, определенный в android.app.Service.

Я называю эту Службу (myService) из Деятельности.

MyService - это:

public class myService extends Service{

 public IBinder onBind(Intent intent){
    return null;
}

public void onCreate(){
    super.onCreate();
    TimerTask task = new TimerTask(){
        public void run(){
            Log.i("test","service running");
            checkDate();            
        }           
    };
    timer = new Timer();
    timer.schedule(task, 0, 20000);
}

 public void checkDate(){
    Toast toast = Toast.makeText(this, "SIMPLE MESSAGE!", Toast.LENGTH_LONG);
    toast.show();
}

}

Метод checkDate() находится в классе myService.

Произошла ошибка:

 09-19 15:41:35.267: E/AndroidRuntime(2026): FATAL EXCEPTION: Timer-0
 09-19 15:41:35.267: E/AndroidRuntime(2026): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
 09-19 15:41:35.267: E/AndroidRuntime(2026):    at android.os.Handler.<init>(Handler.java:121)
 09-19 15:41:35.267: E/AndroidRuntime(2026):    at android.widget.Toast$TN.<init>(Toast.java:310)
 09-19 15:41:35.267: E/AndroidRuntime(2026):    at android.widget.Toast.<init>(Toast.java:84)
 09-19 15:41:35.267: E/AndroidRuntime(2026):    at android.widget.Toast.makeText(Toast.java:226)

2 ответа

Решение

TimerTask работает в отдельном потоке. Toast.makeText() должен быть выполнен из потока, который установил Handler/Looper, По сути, это означает, что вам нужно сделать тост в потоке, в котором работает стандартный диспетчер сообщений / событий Android.

Самый простой способ сделать это будет в вашем checkDate() метод:

runOnUiThread(new Runnable() {
    public void run() {
        Toast toast = Toast.makeText(this, "SIMPLE MESSAGE!", Toast.LENGTH_LONG);
        toast.show();
    }
 });

РЕДАКТИРОВАТЬ: Я идиот, это не правильно. Вы не можете вызвать runOnUiThread() из контекста службы

Вам нужно использовать обработчик для этого. К вашим услугам:

private Handler handler;

в onCreate() вашего сервиса:

handler = new Handler();

в checkDate() метод:

handler.post(new Runnable() {
    public void run() {
        Toast toast = Toast.makeText(myService.this, "SIMPLE MESSAGE!", Toast.LENGTH_LONG);
        toast.show();
    }
 });

Вы звоните из рабочего потока. Вам необходимо вызвать Toast.makeText() (и большинство других функций, связанных с пользовательским интерфейсом) из основного потока. Вы можете использовать обработчик, например.

Вам нужно вызвать Toast.makeText (...) из потока пользовательского интерфейса:

activity.runOnUiThread(new Runnable() {
  public void run() {
    Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
  }
});
Другие вопросы по тегам