8

重複の可能性:
Service から開始された Android Toast が 1 回だけ表示される

私はandroid.app.Serviceで定義されたService Androidを使用しています。

このサービス (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)
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();
    }
 });

編集:私はばかです、それは正しくありません。Service コンテキストから 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 に答える