2012-02-13 10 views
6

C'è un modo per impedire il riavvio automatico del mio servizio da parte di ActivityManager dopo che si "blocca"? In alcuni scenari, chiudo con forza il mio servizio all'uscita del programma, ma non voglio che Android continui a riavviarlo.Android: come impedire al servizio di riavviarsi dopo un arresto anomalo?

+1

Mostra la tua implementazione scheletrica del servizio. –

+0

È un servizio regolare o un IntentService? –

risposta

1

Il servizio può memorizzare un valore in SharedPreferences. Ad esempio è possibile memorizzare qualcosa di simile ogni volta che si avvia il servizio: store ("serviceStarted", 1);

Quando il servizio termina regolarmente (si invia un messaggio per farlo) si sostituisce questo valore: store ("serviceStarted", 0);

Quando la volta successiva che il servizio si riavvia, rileva che il valore di servizioStarted è "1", ovvero che il servizio non è stato arrestato regolarmente e si è riavviato automaticamente. Quando rilevi questo il tuo servizio può chiamare: stopSelf(); cancellare se stesso.

Per maggiori informazioni: http://developer.android.com/reference/android/app/Service.html#ServiceLifecycle

30

Questo comportamento è definito dal valore di ritorno della onStartCommand() nel vostro Service implementazione. La costante START_NOT_STICKY indica a Android di non riavviare il servizio se è in esecuzione mentre il processo è "ucciso". In altre parole:

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    // We don't want this service to continue running if it is explicitly 
    // stopped, so return not sticky. 
    return START_NOT_STICKY; 
} 

HTH

+3

Anche se non contrassegnato come soluzione accettata, questa è la risposta corretta – scooterman

+0

Non funzionerà se ci sono intenti in sospeso. Ho questo problema e l'approccio sopra non funziona. L'approccio sotto potrebbe essere un'alternativa migliore ma non l'ho ancora implementato. Ho provato altri approcci suggeriti nello stack overflow ma non hanno ancora avuto successo. –

+0

@BrianReinhold il tuo problema suona come se avesse una svolta specifica in questa domanda, hai pubblicato uno dei tuoi spiegando il tuo caso d'uso e i problemi che hai osservato? Sarei interessato a esaminarlo di più. – Devunwired

5

Ecco la soluzione mi è venuta in caso potrebbe aiutare qualcun altro. La mia app è stata riavviata anche con START_NOT_STICKY. Così, invece, controllo se l'intento è null, il che significa che il servizio è stato riavviato dal sistema.

@Override 
public int onStartCommand(@Nullable Intent intent, int flags, int startId) { 
    // Ideally, this method would simply return START_NOT_STICKY and the service wouldn't be 
    // restarted automatically. Unfortunately, this seems to not be the case as the log is filled 
    // with messages from BluetoothCommunicator and MainService after a crash when this method 
    // returns START_NOT_STICKY. The following does seem to work. 
    Log.v(LOG_TAG, "onStartCommand()"); 
    if (intent == null) { 
     Log.w(LOG_TAG, "Service was stopped and automatically restarted by the system. Stopping self now."); 
     stopSelf(); 
    } 
    return START_STICKY; 
} 
+0

Grazie! Avevo bisogno di recuperare frequenti aggiornamenti di posizione e inviarlo al server dal servizio. servizio di foreground basato sulla notifica, ma ha smesso di ricevere gli aggiornamenti di posizione, ogni volta che l'applicazione è stata chiusa. Dopo 2 giorni di conflitto, ho raggiunto la risposta e ottimizzato il codice. Prima di 'stopSelf()', ho configurato il riavvio dello stesso servizio utilizzando 'AlarmManager' dopo un ritardo di dire 10 secondi per ora.E questo ha funzionato molto bene, ora ottenendo continuamente aggiornamenti di posizione dal servizio. Molte grazie! – manoj

Problemi correlati