START_STICKY y START_NOT_STICKY
¿ Cuál es la diferencia entre START_STICKY
y START_NOT_STICKY
al implementar servicios en Android? ¿Alguien podría señalar algunos ejemplos estándar?
Ambos códigos sólo son relevantes cuando el teléfono se queda sin memoria y finaliza el servicio antes de que termine de ejecutarse. START_STICKY
le dice al sistema operativo que vuelva a crear el servicio después de que tenga suficiente memoria y que onStartCommand()
vuelva a llamar con una intención nula. START_NOT_STICKY
le dice al sistema operativo que no se moleste en recrear el servicio nuevamente. También hay un tercer código START_REDELIVER_INTENT
que le indica 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 los antecedentes de esto mucho mejor 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 finaliza mientras se está ejecutando:
START_STICKY es básicamente el mismo que el comportamiento anterior, donde el servicio se deja "iniciado" y luego el sistema lo reiniciará. La única diferencia con las versiones anteriores de la plataforma es que, si se reinicia porque su proceso finaliza, se llamará a onStartCommand() en la siguiente instancia del servicio con una intención nula en lugar de no ser llamado en absoluto. Los servicios que utilizan este modo siempre deben comprobar 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 para entregar, entonces el servicio se detendrá en lugar de reiniciarse. Esto tiene mucho más sentido para los servicios que están destinados a ejecutarse únicamente mientras ejecutan los comandos que se les envían. Por ejemplo, se puede iniciar un servicio cada 15 minutos a partir de una alarma para sondear algún estado de la red. Si se apaga mientras hace ese trabajo, sería mejor dejar que se detenga y comenzar la próxima vez que se dispare la alarma.
START_REDELIVER_INTENT es como START_NOT_STICKY, excepto que si el proceso del servicio finaliza antes de llamar a stopSelf() para una intención determinada, esa intención se le volverá a entregar hasta que se complete (a menos que después de varios intentos aún no pueda completarse, momento en el que el sistema se da por vencido). Esto es útil para los servicios que reciben comandos de trabajo por realizar y desean asegurarse de que eventualmente completen el trabajo para cada comando enviado.
BESO respuesta
Diferencia:
START_STICKY
el sistema intentará recrear su servicio después de que se elimine
START_NOT_STICKY
el sistema no intentará recrear su servicio después de que se elimine
Ejemplo estándar:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
La documentación para START_STICKY
y START_NOT_STICKY
es bastante sencilla.
START_STICKY:
Si el proceso de este servicio se finaliza mientras se inicia (después de regresar de
onStartCommand(Intent, int, int))
, déjelo en el estado iniciado pero no conserve esta intención entregada. Más adelante, el sistema intentará volver a crear el servicio. Debido a que está en el estado iniciado , garantizará la llamadaonStartCommand(Intent, int, int)
después de crear la nueva instancia de servicio; si no hay ningún comando de inicio pendiente para entregar al servicio, se llamará con un objeto de intención nula, por lo que debe tener cuidado de verificar esto.Este modo tiene sentido para cosas que se iniciarán y detendrán explícitamente para ejecutarse durante períodos de tiempo arbitrarios, como un servicio que reproduce música de fondo.
Ejemplo: muestra de servicio local
START_NOT_STICKY:
Si el proceso de este servicio finaliza mientras se inicia (después de regresar de
onStartCommand(Intent, int, int))
, y no hay nuevos intentos de inicio para entregarle, saque el servicio del estado iniciado y no lo vuelva a crear hasta una futura llamada explícita aContext.startService(Intent)
. El servicio no recibirá unaonStartCommand(Intent, int, int)
llamada con unnull
Intent porque no se reiniciará si no hay Intents pendientes para entregar.Este modo tiene sentido para cosas que quieren hacer algo de trabajo como resultado de haber sido iniciadas, pero se pueden detener cuando están bajo presión de memoria y se reiniciarán explícitamente más tarde para hacer más trabajo. Un ejemplo de un servicio de este tipo sería uno que sondea datos de un servidor: podría programar una alarma para sondear cada
N
minutos haciendo que la alarma inicie su servicio. Cuando se leonStartCommand(Intent, int, int)
llama desde la alarma, programa una nueva alarma para N minutos después y genera un hilo para realizar la conexión en red. Si su proceso se interrumpe mientras se realiza esa verificación, el servicio no se reiniciará hasta que suene la alarma.
Ejemplo: ServiceStartArguments.java
START_STICKY
: Reiniciará el servicio en caso de que finalice y los datos de Intent que se pasan alonStartCommand()
método seanNULL
. Esto es adecuado para el servicio que no ejecuta comandos sino que se ejecuta de forma independiente y espera el trabajo.START_NOT_STICKY
: No reiniciará el servicio y es útil para los servicios que se ejecutarán periódicamente. El servicio se reiniciará sólo cuando hayastartService()
llamadas pendientes. Es la mejor opción para evitar ejecutar un servicio en caso de que no sea necesario.START_REDELIVER_INTENT
: Es lo mismoSTAR_STICKY
y recrea el servicio, llamaonStartCommand()
con la última intención que se entregó al servicio.