Ошибка вызова тоста из Сервиса 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();
}
});