2012-09-19 3 views
8

Possible Duplicate:
Android Toast started from Service only displays onceFehler Toast von Service-Android ruft

I Service Android bin mit in android.app.Service definiert.

Ich nenne diesen Service (myService) von einer Aktivität.

MyService ist:

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(); 
} 

} 

Verfahren checkdate() befindet sich in der Klasse myService.

Der Fehler produziert wird:

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) 
+0

Können Sie den Code schreiben Sie verwenden, um dies zu beginnen? Ist dies auch ein Android-Dienst oder ist es nur ein Hintergrund-Thread? Das Problem besteht darin, dass Sie nicht mit der Benutzeroberfläche aus einem Hintergrundthread interagieren können. Wenn Sie einen Verweis auf den Aktivitätskontext haben, können Sie runOnUIThread mit diesem Kontext aufrufen. – Bobbake4

Antwort

23

TimerTask läuft in einem separaten Thread. Toast.makeText() muss von einem Thread ausgeführt werden, der eine festgelegt hat. Das bedeutet im Wesentlichen, dass Sie den Toast auf einen Thread anwenden müssen, auf dem der Standard-Android-Nachrichten-/Event-Dispatcher läuft.

Der einfachste Weg, dies zu tun in Ihrem checkDate() Methode wäre:

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

EDIT: Ich bin ein Idiot, das ist nicht richtig. Sie können runOnUiThread() nicht aus einem Service-Kontext aufrufen

Sie müssen hierfür einen Handler verwenden. In Ihren Diensten:

private Handler handler; 

in onCreate() Ihrer Dienstleistung:

handler = new Handler(); 

in checkDate() Methode:

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

Ich habe dies versucht, aber gebe diesen Fehler zurück: Die Methode runOnUiThread (new Runnable() {}) ist nicht definiert für den Typ myService – GVillani82

+0

Sorry, ich bin ein Idiot. Ich habe meinen Beitrag entsprechend bearbeitet. Sie müssen hierfür einen Handler verwenden. –

+0

Ok. Es gibt nur ein weiteres Problem bei "makeText": Die Methode makeText (Context, CharSequence, int) im Toast-Typ ist nicht anwendbar für die Argumente (new Runnable() {}, String, int) – GVillani82

4

Sie es von einem Worker-Thread aufrufen. Sie müssen Toast.makeText() (und die meisten anderen Funktionen, die die Benutzeroberfläche betreffen) innerhalb des Hauptthreads aufrufen. Sie könnten zum Beispiel einen Handler verwenden.

Sie benötigen Toast.makeText (...) aus dem UI-Thread nennen:

activity.runOnUiThread(new Runnable() { 
    public void run() { 
    Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show(); 
    } 
}); 
+0

+1 Hoppla, du hast mich dazu geschlagen. –

+0

Wenn ich dies versuche, bekomme ich diesen Fehler: Kann keine statische Referenz auf die nicht-statische Methode runOnUiThread (Runnable) vom Typ Aktivität – GVillani82

+2

Ja, das funktioniert nicht, es sei denn, Sie haben einen Aktivitätskontext, den Sie nicht haben . –