2012-06-21 10 views
7

Quando si effettua questa richiamata nella mia app, ho un bel po 'di lavoro da fare (leggere & scrivere in SQL db attraverso una lib di ORM e un numero di calcoli basati sulla distanza). Naturalmente sono preoccupato di non bloccare il thread dell'interfaccia utente principale, quindi ho cercato (senza successo) di scoprire se questo è il thread su cui è stato creato il callback. Se lo è, ho intenzione di fare tutto il lavoro di cui sopra su un AsyncTask attivato quando viene effettuata la richiamata. Questo stesso AsyncTask riceverà anche eventi da 2 classi di attività separate. (Rispondendo all'input dell'utente ecc.)onLocationChanged callback viene effettuato su quale thread? Il thread principale dell'interfaccia utente?

Gran parte della discussione che ho trovato su questo callback sembra essere basata su persone che cercano di cambiare il thread su cui è effettivamente ricevuto il callback. Questo non ha senso per me. Sicuramente la piattaforma determina il contesto di questa richiamata e la cosa sensata da fare quando viene ricevuta è scaricare qualsiasi lavoro serio su un altro thread, per il quale AsyncTask sembra appropriato.

Se qualcuno può delineare un modello di successo che hanno usato qui sarebbe davvero utile.

risposta

7

Secondo la documentazione di riferimento per Android LocationManager:

il thread chiamante deve essere un filo del crochet, come il filo conduttore della la chiamata Activity.

Ciò significa che il thread che inizializza il callback deve essere il thread principale o un thread Looper.

Ho trovato il modo migliore per gestire questo è quello di registrare un ricevitore OnLocationChanged nella discussione principale. Quindi, nel mio callback creerò un Runnable da inviare a uno sfondo Thread in cui eseguirò qualsiasi attività di lunga durata (come scrivere sul database).

ExecutorService mThreadPool = Executors.newSingleThreadExecutor(); 

@Override 
public void onLocationChanged(Location location) { 
    mThreadPool.execute(new Runnable() { 
     @Override 
     public void run() { 
      // Perform your long-running tasks here. 
      //... 
     } 
    }); 
} 
+0

Dalla documentazione sembra che il filo su cui onLocationChanged è chiamato nuovamente, dipende dai parametri passati a qualsiasi viene utilizzato requestLocationUpdate (..) chiamata. Inoltre, se un Looper non è uno dei parametri, allora il callback verrà eseguito nel contesto del thread principale dell'interfaccia utente. Hai bisogno di leggere un po 'di più su Loopers. La soluzione sopra sembra sensata. Ora mi sto chiedendo come si confronta con l'utilizzo di un AsyncTask in termini di prestazioni. Quindi andrò a leggere la documentazione come avrei dovuto fare in primo luogo. Grazie per l'aiuto. –

+0

Hai ragione, ci sono diverse opzioni per la registrazione di un callback di 'LocationListener'. La lettura della documentazione è decisamente raccomandata. La soluzione di cui sopra è approssimativamente equivalente all'utilizzo di un 'AsyncTask'. Credo che se guardi all'origine per la classe 'AsyncTask' vedrai che usa internamente un' ExecutorService'. Tuttavia, se non hai bisogno di interagire con il thread dell'interfaccia utente al termine dell'attività, troverai che 'AsyncTask' fa più del necessario. – twaddington