START_STICKY e START_NOT_STICKY


Risposte:


371

Entrambi i codici sono rilevanti solo quando il telefono esaurisce la memoria e uccide il servizio prima che termini l'esecuzione. START_STICKYindica al sistema operativo di ricreare il servizio dopo che ha memoria sufficiente e chiamare di onStartCommand()nuovo con un intento nullo. START_NOT_STICKYindica al sistema operativo di non preoccuparsi di ricreare nuovamente il servizio. C'è anche un terzo codice START_REDELIVER_INTENTche dice al sistema operativo di ricreare il servizio e riconsegnare lo stesso intento onStartCommand().

Questo articolo di Dianne Hackborn ha spiegato lo sfondo molto meglio della documentazione ufficiale.

Fonte: http://android-developers.blogspot.com.au/2010/02/service-api-changes-starting-with.html

La parte chiave qui è un nuovo codice risultato restituito dalla funzione, che dice al sistema cosa dovrebbe fare con il servizio se il suo processo viene interrotto mentre è in esecuzione:

START_STICKY è sostanzialmente lo stesso del comportamento precedente, in cui il servizio viene lasciato "avviato" e verrà successivamente riavviato dal sistema. L'unica differenza rispetto alle versioni precedenti della piattaforma è che se viene riavviato perché il suo processo viene interrotto, onStartCommand () verrà chiamato nella prossima istanza del servizio con un intento nullo invece di non essere chiamato affatto. I servizi che utilizzano questa modalità dovrebbero sempre verificare questo caso e gestirlo in modo appropriato.

START_NOT_STICKY dice che, dopo essere tornato da onStartCreated (), se il processo viene interrotto senza comandi di avvio rimanenti da consegnare, il servizio verrà arrestato anziché riavviato. Questo ha molto più senso per i servizi che devono essere eseguiti solo durante l'esecuzione dei comandi inviati a loro. Ad esempio, un servizio può essere avviato ogni 15 minuti da un allarme per eseguire il polling dello stato della rete. Se viene ucciso mentre fa quel lavoro, sarebbe meglio lasciarlo fermare e iniziare la prossima volta che scatta l'allarme.

START_REDELIVER_INTENT è come START_NOT_STICKY, tranne se il processo del servizio viene interrotto prima che venga chiamato stopSelf () per un determinato intento, tale intento verrà consegnato nuovamente fino al completamento (a meno che dopo un certo numero di ulteriori tentativi non sia ancora possibile completare, a quel punto il sistema si arrende). Questo è utile per i servizi che stanno ricevendo comandi di lavoro da fare e vogliono assicurarsi che alla fine completino il lavoro per ciascun comando inviato.


1
Come evitare la doppia chiamata al task handleStart (intent, startId); come saranno chiamati sia onStart () che onStartCommand? è un buon design? @Frank Leigh
Sazzad Hissain Khan,

2
Qual è il flag predefinito, tuttavia, se non viene specificato nessuno?
IgorGanapolsky,

3
Se segui il "return super.onStartCommand (...);" vedrai che nel caso in cui la tua versione di sdk di destinazione sia inferiore a ECLAIR (API5 = 2.0) per impostazione predefinita, viene restituito START_STICKY_COMPATIBILITY e da 2.0 e versioni successive START_STICKY.
MikeL,

1
Cosa intendi con "senza comandi di avvio rimanenti" in START_NOT_STICKY?
Malwinder Singh,

3
@FrankLeigh Non sono d'accordo che START_REDELIVER_INTENTè come START_NOT_STICKY. Invece è comeSTART_STICKY
CopsOnRoad il

107

Risposta KISS

Differenza:

START_STICKY

il sistema proverà a ricreare il servizio dopo che è stato ucciso

START_NOT_STICKY

il sistema non tenterà di ricreare il servizio dopo che è stato interrotto


Esempio standard:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}

5
Questo in realtà non è corretto e confuso. È un errore che dice: "il servizio è ucciso" perché si può pensare che ti riferisci a stopSelf o stopService, mentre ovviamente ti riferisci al processo ucciso. Quindi è meglio utilizzare il processo di parole nella tua risposta.
Ilya Gazman,

Ciao come posso testare START_REDELIVER_INTENT. Ho appena testato START_STICKYe ucciso l'app da app recenti. Quindi richiama il servizio. Ma START_REDELIVER_INTENTmai più chiamato. Perché?
Asif Mushtaq,

@IlyaGazman Rispetto rispettosamente. Fermati e uccisi sono due parole molto diverse. Questa risposta spiega correttamente il problema in modo semplice e diretto.
NoHarmDan,

23

La documentazione per START_STICKYed START_NOT_STICKYè abbastanza semplice.

START_STICKY:

Se il processo di questo servizio viene interrotto mentre viene avviato (dopo essere tornato da onStartCommand(Intent, int, int)), quindi lasciarlo nello stato avviato ma non mantenere questo intento consegnato. Successivamente il sistema proverà a ricreare il servizio. Perché è nello stato avviato , garantirà di chiamare onStartCommand(Intent, int, int) dopo aver creato la nuova istanza del servizio; se non ci sono comandi di avvio in sospeso da consegnare al servizio, verrà chiamato con un oggetto con intento nullo, quindi devi fare attenzione a verificarlo.

Questa modalità ha senso per le cose che verranno esplicitamente avviate e interrotte per periodi di tempo arbitrari, come un servizio che esegue la riproduzione di musica di sottofondo.

Esempio: esempio di servizio locale

START_NOT_STICKY:

Se il processo di questo servizio viene interrotto mentre viene avviato (dopo essere tornato da onStartCommand(Intent, int, int)), e non ci sono nuovi intenti di avvio da consegnare ad esso, quindi portare il servizio fuori dallo stato avviato e non ricrearlo fino a quando una futura chiamata esplicita a Context.startService(Intent). non riceverà una onStartCommand(Intent, int, int)chiamata con un nullIntento perché non verrà riavviato se non ci sono Intenti in sospeso da consegnare.

Questa modalità ha senso per le cose che vogliono fare un po 'di lavoro a seguito dell'avvio, ma possono essere arrestate quando sono sotto pressione della memoria e si ricominceranno esplicitamente in seguito per fare più lavoro. Un esempio di tale servizio sarebbe quello che esegue il polling per i dati da un server: potrebbe programmare un allarme per il polling ogni Nminuto facendo in modo che l'allarme inizi il suo servizio. Quando onStartCommand(Intent, int, int)viene chiamato dall'allarme, pianifica un nuovo allarme per N minuti dopo e genera un thread per fare il suo networking. Se il processo viene interrotto durante tale controllo, il servizio non verrà riavviato fino a quando non si attiva l'allarme.

Esempio: ServiceStartArguments.java


senza fortuna ragazzi .. Non sono stato in grado di mettere in relazione la documentazione con parole di laici. Mi piacerebbe relazionarmi con uno scenario in tempo reale. Vorrei mostrare un esempio sul dispositivo. in modo che possano capire più facilmente.
prago,

per START_STICKY e START_NOT_STICKY onStartCommand () verranno eseguiti una sola volta e ne usciranno. Ho esaminato il campione che hai indicato, ma il mio dubbio è quante volte verrà eseguito onStartCommand (). se riporto START_STICKY e provo ancora a ricreare il servizio, il servizio verrà eseguito su StartCommand allora ??
prago,

cosa succede all'attività quando viene ricreato il servizio? Anche l'attività viene ricreata?
riscatto

Immagino che non lo sapremo mai
Denny il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.