2012-05-18 2 views
7

Dopo aver letto la maggior parte della documentazione disponibile sui servizi Android sul sito degli sviluppatori e qui in StackOverflow, sono ancora confuso da diversi aspetti dell'esecuzione di un servizio in un'attività separata. Spero che qualcuno possa mettermi sulla strada giusta.Come avviare un'attività in background di lunga durata nel servizio Android

Diciamo che abbiamo quadro servizio trival come

public class HliService extends Service { 

    @Override 
    public void onCreate() { 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     // If we get killed, after returning from here, restart 
     return START_STICKY; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     // We don't provide binding, so return null 
     return null; 
    } 

    @Override 
    public void onDestroy() { 
    } 
} 

e nel manifesto, ho

<service android:name=".HliService" android:process=":HLI_Comms"/> 

in modo che il servizio viene eseguito nel proprio thread.

L'intento del servizio è quello di fornire un'attività in background che comunichi a un dispositivo che utilizza un socket TCP e altre cose. A rischio di ignorare i problemi della batteria ecc, in fondo mi piacerebbe funzionare per sempre.

Qualcosa di simile

// Method that communicates using a TCP socket, and needs to send 
// information back to the activity and receive messages from activity 
// not shown here. 
private void dummytask() { 

    boolean keepGoing = true; 
    while (keepGoing) { 
     // do useful stuff in here 
     // sets keepGoing false at some point 
    } 
    stopSelf(); 
} 

Qual è il modo migliore per iniziare questo metodo/compito?

Ho visto il codice nel sito degli sviluppatori che utilizza un gestore di messaggi e un looper, che in parte comprendo solo parzialmente, ma sembra molto complicato e forse più di quanto richiedo?

Non credo di poter chiamare questo metodo da onCreate() o onStartCommand() da allora nessuno dei due si completerebbe se richiamato dal sistema? Dovrei avviarlo con un timer o un allarme?

Avrò bisogno di aggiungere un gestore di messaggi per comunicare con l'attività gui, ma poiché sto avviando il servizio in un altro thread (in virtù dell'istruzione manifest "processo"), devo invece usare AIDL ?

Ho anche cercato di utilizzare AysnchTask piuttosto che estendere il servizio, ma sembra più adatto all'esecuzione di un'attività e quindi alla chiusura.

+0

'while (keepGoing)' - se questo è in un thread diverso da quello che imposta 'keepGoing' su false' keepGoing' DEVE ESSERE 'volatile' - leggere sul modello di memoria Java –

+0

Si prega di consultare questa risposta questo può aiutare . [ENTER Descrizione Link qui] [1] [1]: http://stackoverflow.com/a/13783477/2165080 –

risposta

2

in modo che il servizio venga eseguito in una propria thread.

Che inserisce il servizio nel proprio processo . Questo è generalmente qualcosa da evitare, poiché consuma RAM e CPU extra (per IPC). È possibile creare un thread semplicemente creando uno Thread o un numero qualsiasi di altri mezzi, la maggior parte dei quali sono stati in Java per circa un decennio.

A rischio di ignorare i problemi di batteria ecc., In pratica mi piacerebbe che fosse eseguito per sempre.

È praticamente impossibile che un servizio funzioni per sempre. Gli utenti o il sistema operativo si libereranno del servizio alla fine.

Qual è il modo migliore per avviare questo metodo/attività?

Chiama dummytask() da un thread in background.

ho invece bisogno di utilizzare AIDL?

No. Il servizio può trasmettere un Intent, o di invocare un PendingIntent fornito dall'attività, oppure mandare un Message tramite un Messenger fornito dalla attività, ecc La migliore sarebbe quella di utilizzare il LocalBroadcastManager dal supporto Android pacchetto, ma ciò non funzionerà oltre i limiti del processo, obbligandoti a opzioni di comunicazione più costose.

+0

Ok - grazie @CommonsWare. Ho anche esaminato questo metodo, ma sono anche incerto su alcuni aspetti della sua implementazione - farò ulteriori ricerche e forse pubblicherò una domanda di follow-up. Prenderò il tuo consiglio su non usare il "processo". A proposito, so che il servizio non funzionerà mai per sempre - era solo una semplificazione. Grazie ancora. – SteveJP

+0

@CommonsWare Grazie per la spiegazione di cui sopra ... davvero bello – Biplab

0

Penso che si possa usare uno IntentService che si esegue impostando un allarme (regolare) (AlarmManager.setRepeating) con uno PendingIntent in esso. È possibile inviare notifiche all'interfaccia utente trasmettendo un'intenzione dallo IntentService e ricevendola nell'interfaccia utente tramite BroadcastReceiver.

+0

Grazie a @omoling: non è più adatto a eseguire solo una piccola attività e quindi a terminare, piuttosto che avviare un processo di lunga durata? – SteveJP