2012-09-19 9 views
8

Possible Duplicate:
Android Toast started from Service only displays onceerrore chiamando brindisi dal Servizio Android

Sto utilizzando il servizio di Android definito android.app.Service.

Io chiamo questo servizio (myService) da un'attività.

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

} 

Il metodo checkdate() risiede nel myService di classe.

L'errore prodotta è:

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

potete inserire il codice che si utilizza per iniziare questo? Inoltre questo è un vero servizio Android o è solo un thread in background? Il problema è che non puoi interagire con l'interfaccia utente da un thread in background. Se hai un riferimento al contesto di attività puoi chiamare runOnUIThread usando quel contesto. – Bobbake4

risposta

23

TimerTask viene eseguito in un thread separato. Toast.makeText() deve essere eseguito da un thread che ha stabilito un Handler/Looper. Fondamentalmente questo significa che devi fare il brindisi su un thread in cui è in esecuzione il dispatcher di messaggi/eventi Android standard.

Il modo più semplice per fare questo sarebbe nel metodo checkDate():

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

EDIT: io sono un idiota, che non è giusto. Non è possibile chiamare runOnUiThread() da un contesto di servizio

È necessario utilizzare un gestore per questo. Nel vostro servizio:

private Handler handler; 

in onCreate() del vostro servizio:

handler = new Handler(); 

in checkDate() metodo:

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

Ho provato, ma restituisco questo errore: Il metodo runOnUiThread (new Runnable() {}) non è definito per il tipo myService – GVillani82

+0

Scusa, sono un idiota. Ho modificato il mio post di conseguenza. È necessario utilizzare un gestore per questo. –

+0

Ok. C'è solo un altro problema su "makeText": Il metodo makeText (Context, CharSequence, int) nel tipo Toast non è applicabile per gli argomenti (new Runnable() {}, String, int) – GVillani82

4

si sta chiamando da un thread di lavoro. Devi chiamare Toast.makeText() (e la maggior parte delle altre funzioni relative all'interfaccia utente) all'interno della discussione principale. Potresti usare un gestore, per esempio.

è necessario chiamare Toast.makeText (...) dal thread dell'interfaccia utente:

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

+1 Ooops, mi hai battuto. –

+0

Se provo questo, ottengo questo errore: Impossibile creare un riferimento statico al metodo non statico runOnUiThread (Runnable) dal tipo Attività – GVillani82

+2

Sì, questo non funziona a meno che tu non abbia un contesto di attività, che non hai . –

Problemi correlati