2012-06-25 5 views
18

Ho un servizio Android che avvia e mantiene un thread in background.Esegui codice sul thread principale in Android senza accedere ad un'attività?

Di tanto in tanto, il thread in background deve eseguire una richiamata sul thread principale. Sono perplesso su come farlo.

Non riesco a chiamare this.runOnUiThread perché "this" è un'istanza di Service, non Activity e un servizio non ha il metodo runOnUiThread.

Non riesco nemmeno a creare o eseguire un AsyncTask, poiché la documentazione di AsyncTask indica che sia il costruttore che il metodo di esecuzione devono essere richiamati dal thread dell'interfaccia utente.

Devo mantenere un riferimento all'attività che sta utilizzando il servizio e chiamare il suo metodo runOnUiThread oppure esiste un altro modo per eseguire qualcosa sul thread dell'interfaccia utente?

Grazie.

+3

"il thread in background deve eseguire una richiamata sul thread principale" - perché? – CommonsWare

+0

L'utente del servizio è un'attività. Ha bisogno di callback sul thread principale in modo che possa aggiornare gli elementi dell'interfaccia utente. Suppongo che potrei richiamarlo sul thread in background e renderlo responsabile della pianificazione di un callback del thread dell'interfaccia utente, ma sarebbe più conveniente per il consumatore del servizio se potessi farlo. –

+3

@Cruceo: Oh, cieli no. – CommonsWare

risposta

2

L'attività deve can associazione al servizio.

http://developer.android.com/guide/components/bound-services.html

In particolare, date un'occhiata alla creazione di un messaggero in quella pagina. L'attività del client può fornire un oggetto messenger che risponde ai messaggi dal servizio e, una volta ricevuto, eseguire qualsiasi codice UI necessario sul thread dell'interfaccia utente utilizzando un gestore.

NON mantenere il riferimento dell'attività nel servizio. Questo può portare a tutti i tipi di problemi di memoria.

+0

Mentre 'Messenger' è un'ottima soluzione, non è necessario collegarsi al servizio per utilizzarlo. 'Messenger' è' Parcelable' e può essere inviato in un comando 'Intent' in un comando inviato tramite' startService() '. – CommonsWare

1

Sicuro. Vedi Handler. È possibile fornire al servizio un oggetto gestore e quando il servizio deve eseguire alcune attività eseguibili sul thread dell'interfaccia utente, è sufficiente chiamare handler.post (some_runnable_task). Questa chiamata Puoi trovare un esempio in questo link 4.Tutorial: Handler.

9

Ha bisogno di callback sul thread principale in modo che possa aggiornare gli elementi dell'interfaccia utente.

Utilizzare LocalBroadcastManager e fare in modo che il servizio invii una trasmissione, da prelevare dall'attività, che la otterrà sul thread dell'applicazione principale. Here is a sample application demonstrating this.

Oppure utilizzare una trasmissione "reale" con sendBroadcast().

Oppure, utilizzare Messenger, come si è detto you786, legato a Handler, come indicato da Guillermo, anche se non è necessario utilizzare obbligatoriamente il binding.

53

Sto usando il seguente codice di volta in volta se non tengo accesso diretto all'attività (per un motivo o un altro);

new Handler(Looper.getMainLooper()).post(mYourUiThreadRunnable); 
+4

Ho pensato che potrebbe essere obsoleto, ma ancora alla fine del 2015 questo è il modo consigliato: http://developer.android.com/training/multiple-threads/communicate-ui.html – gaborsch

Problemi correlati