8

可能重复:
从服务启动的 Android Toast 仅显示一次

我正在使用 android.app.Service 中定义的 Service Android。

我从一个活动中调用这个服务(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)
4

2 回答 2

23

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();
    }
 });
于 2012-09-19T15:58:16.923 回答
4

您从工作线程中调用它。您需要从主线程中调用 Toast.makeText() (以及处理 UI 的大多数其他函数)。例如,您可以使用处理程序。

您需要从 UI 线程调用 Toast.makeText(...) :

activity.runOnUiThread(new Runnable() {
  public void run() {
    Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
  }
});
于 2012-09-19T15:54:17.877 回答