START_STICKY y START_NOT_STICKY

Respuestas:

371

Ambos códigos solo son relevantes cuando el teléfono se queda sin memoria y mata el servicio antes de que termine de ejecutarse. START_STICKYle dice al sistema operativo que onStartCommand()vuelva a crear el servicio después de que tenga suficiente memoria y vuelva a llamar con una intención nula. START_NOT_STICKYle dice al sistema operativo que no se moleste en recrear el servicio nuevamente. También hay un tercer código START_REDELIVER_INTENTque le dice al sistema operativo que vuelva a crear el servicio y vuelva a entregar la misma intención onStartCommand().

Este artículo de Dianne Hackborn explica mucho mejor los antecedentes de esto que la documentación oficial.

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

La parte clave aquí es un nuevo código de resultado devuelto por la función, que le dice al sistema qué debe hacer con el servicio si su proceso se anula mientras se está ejecutando:

START_STICKY es básicamente el mismo comportamiento anterior, donde el servicio se deja "iniciado" y luego el sistema lo reiniciará. La única diferencia con respecto a las versiones anteriores de la plataforma es que si se reinicia porque su proceso se cancela, se llamará a onStartCommand () en la próxima instancia del servicio con un Intento nulo en lugar de no ser llamado en absoluto. Los servicios que usan este modo siempre deben verificar este caso y tratarlo adecuadamente.

START_NOT_STICKY dice que, después de regresar de onStartCreated (), si el proceso finaliza sin que queden comandos de inicio, el servicio se detendrá en lugar de reiniciarse. Esto tiene mucho más sentido para los servicios que están destinados a ejecutarse solo mientras se ejecutan los comandos que se les envían. Por ejemplo, se puede iniciar un servicio cada 15 minutos desde una alarma para sondear algún estado de la red. Si se mata mientras se hace ese trabajo, lo mejor sería dejar que se detenga y comenzar la próxima vez que se active la alarma.

START_REDELIVER_INTENT es como START_NOT_STICKY, excepto si el proceso del servicio se cancela antes de que llame a stopSelf () para un intento determinado, ese intento se volverá a entregar hasta que se complete (a menos que después de varios intentos más aún no pueda completarse, en ese punto el sistema se da por vencido). Esto es útil para los servicios que reciben comandos de trabajo y desean asegurarse de que eventualmente completen el trabajo para cada comando enviado.

Frank Leigh
fuente
1
Cómo evitar la doble llamada a la tarea handleStart (intent, startId); como se llamará tanto a onStart () como a onStartCommand? ¿Es un buen diseño? @Frank Leigh
Sazzad Hissain Khan
2
Sin embargo, ¿cuál es el indicador predeterminado si no se especifica ninguno?
IgorGanapolsky
3
Si sigue el "return super.onStartCommand (...);" verá que en caso de que su versión de SDK de destino sea menor que ECLAIR (API5 = 2.0) de forma predeterminada, se devuelve START_STICKY_COMPATIBILITY y desde 2.0 y superiores se devuelve START_STICKY.
MikeL
1
¿Qué quieres decir con "sin comandos de inicio restantes" en START_NOT_STICKY?
Malwinder Singh
3
@FrankLeigh No estoy de acuerdo en que START_REDELIVER_INTENTsea ​​así START_NOT_STICKY. En cambio, es comoSTART_STICKY
CopsOnRoad
107

BESO respuesta

Diferencia:

START_STICKY

el sistema intentará recrear su servicio después de que se elimine

START_NOT_STICKY

el sistema no intentará volver a crear su servicio después de que se elimine


Ejemplo estándar:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}
Oded Breiner
fuente
55
Esto en realidad no es correcto y confuso. Es un error decir: "el servicio se interrumpe" porque uno puede pensar que se refiere a stopSelf o stopService, mientras que obviamente se refiere al proceso finalizado. Así que mejor usa el proceso de palabras en tu respuesta.
Ilya Gazman
Hola ¿Cómo puedo probar START_REDELIVER_INTENT. Acabo de probar START_STICKYy eliminar la aplicación con aplicaciones recientes. Entonces recuerda el servicio. Pero START_REDELIVER_INTENTnunca volvió a llamar. ¿Por qué?
Asif Mushtaq
@IlyaGazman Estoy respetuosamente en desacuerdo. Detenido y asesinado son dos palabras muy diferentes. Esta respuesta explica el problema correctamente de una manera simple y directa.
NoHarmDan
23

La documentación para START_STICKYy START_NOT_STICKYes bastante sencilla.

START_STICKY:

Si el proceso de este servicio se interrumpe mientras se inicia (después de regresar onStartCommand(Intent, int, int)), déjelo en el estado iniciado pero no conserve esta intención entregada. Más tarde, el sistema intentará volver a crear el servicio. Porque está en el estado iniciado , garantizará llamar onStartCommand(Intent, int, int) después de crear la nueva instancia de servicio; si no hay ningún comando de inicio pendiente para ser entregado al servicio, se llamará con un objeto de intento nulo, por lo que debe asegurarse de verificar esto.

Este modo tiene sentido para cosas que se iniciarán explícitamente y se detendrán para que se ejecuten durante períodos de tiempo arbitrarios, como un servicio que realiza la reproducción de música de fondo.

Ejemplo: muestra de servicio local

START_NOT_STICKY:

Si el proceso de este servicio se interrumpe mientras se inicia (después de regresar de onStartCommand(Intent, int, int)), y no hay nuevos intentos de inicio para entregarlo, entonces saque el servicio del estado iniciado y no lo vuelva a crear hasta una futura llamada explícita Context.startService(Intent). no recibirá una onStartCommand(Intent, int, int)llamada con una nullintención porque no se reiniciará si no hay intenciones pendientes para entregar.

Este modo tiene sentido para las cosas que desean hacer algo de trabajo como resultado de su inicio, pero se pueden detener cuando están bajo presión de memoria y se iniciarán explícitamente nuevamente más tarde para hacer más trabajo. Un ejemplo de dicho servicio sería uno que sondea los datos de un servidor: podría programar una alarma para sondear cada Nminuto haciendo que la alarma inicie su servicio. Cuando onStartCommand(Intent, int, int)se llama desde la alarma, programa una nueva alarma para N minutos más tarde, y genera un hilo para hacer su red. Si su proceso finaliza mientras se realiza esa verificación, el servicio no se reiniciará hasta que se active la alarma.

Ejemplo: ServiceStartArguments.java

Marvin Pinto
fuente
sin suerte chicos ... No pude relacionar la documentación en palabras sencillas. Me gustaría relacionarme con un escenario en tiempo real. Me gustaría mostrar un ejemplo en el dispositivo. para que puedan entender más fácilmente.
prago 03 de
para START_STICKY y START_NOT_STICKY onStartCommand () se ejecutará solo una vez y saldrá de él. Revisé la muestra que señaló, pero mi duda es cuántas veces se ejecutará onStartCommand (). si vuelvo a probar START_STICKY y aún intento volver a crear el servicio, ¿se ejecutará el servicio en StartCommand entonces?
prago
¿Qué sucede con la actividad cuando se vuelve a crear el servicio? ¿La actividad también se vuelve a crear?
ransh
Supongo que nunca lo sabremos
Denny