START_STICKY e START_NOT_STICKY

Respostas:

371

Ambos os códigos são relevantes apenas quando o telefone fica sem memória e mata o serviço antes de concluir a execução. START_STICKYinforma ao sistema operacional para recriar o serviço depois que ele tiver memória suficiente e chame onStartCommand()novamente com uma intenção nula. START_NOT_STICKYdiz ao sistema operacional para não se preocupar em recriar o serviço novamente. Há também um terceiro código START_REDELIVER_INTENTque informa ao sistema operacional para recriar o serviço e reenviar a mesma intenção onStartCommand().

Este artigo de Dianne Hackborn explicou os antecedentes disso muito melhor do que a documentação oficial.

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

A parte principal aqui é um novo código de resultado retornado pela função, informando ao sistema o que deve ser feito com o serviço se o processo for interrompido enquanto estiver em execução:

START_STICKY é basicamente o mesmo que o comportamento anterior, onde o serviço é deixado "iniciado" e mais tarde será reiniciado pelo sistema. A única diferença das versões anteriores da plataforma é que, se ela for reiniciada porque seu processo foi interrompido, onStartCommand () será chamado na próxima instância do serviço com uma Intent nula, em vez de não ser chamado. Os serviços que usam esse modo sempre devem verificar esse caso e lidar com ele adequadamente.

START_NOT_STICKY diz que, após retornar de onStartCreated (), se o processo for interrompido sem nenhum comando de inicialização restante para entregar, o serviço será interrompido em vez de reiniciado. Isso faz muito mais sentido para serviços destinados a serem executados apenas durante a execução de comandos enviados a eles. Por exemplo, um serviço pode ser iniciado a cada 15 minutos a partir de um alarme para pesquisar algum estado da rede. Se ele for morto durante esse trabalho, seria melhor deixá-lo parar e começar na próxima vez que o alarme disparar.

START_REDELIVER_INTENT é como START_NOT_STICKY, exceto se o processo do serviço for interrompido antes de chamar stopSelf () para uma determinada intenção, essa intenção será entregue novamente até que seja concluída (a menos que após várias tentativas ainda não seja concluída, momento em que o sistema desiste). Isso é útil para os serviços que estão recebendo comandos de trabalho e deseja garantir que eles concluam o trabalho para cada comando enviado.

Frank Leigh
fonte
1
Como evitar a chamada dupla para a tarefa handleStart (intent, startId); como onStart () e onStartCommand serão chamados? é um bom design? @Frank Leigh
Sazzad Hissain Khan
2
Qual é o sinalizador padrão, se nenhum for especificado?
IgorGanapolsky
3
Se você seguir o "return super.onStartCommand (...);" você verá que, no caso de sua versão sdk de destino ser menor que ECLAIR (API5 = 2.0), por padrão, o START_STICKY_COMPATIBILITY será retornado e a partir de 2.0 e superior START_STICKY será retornado.
MikeL
1
O que você quer dizer com "sem comandos de início restantes" em START_NOT_STICKY?
Malwinder Singh
3
@FrankLeigh Não concordo que START_REDELIVER_INTENTseja assim START_NOT_STICKY. Em vez disso, é comoSTART_STICKY
CopsOnRoad
107

Resposta do KISS

Diferença:

START_STICKY

o sistema tentará recriar seu serviço depois que ele for morto

START_NOT_STICKY

o sistema não tentará recriar seu serviço depois que ele for morto


Exemplo padrão:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}
Oded Breiner
fonte
5
Na verdade, isso não é correto e confuso. É um erro dizer: "o serviço está morto" porque se pode pensar que você se refere a stopSelf ou stopService, enquanto você obviamente se refere ao processo morto. Então é melhor você usar o processo de palavras em sua resposta.
Ilya Gazman 01/12/16
Oi como eu posso testar START_REDELIVER_INTENT. Acabei de testar START_STICKYe matar o aplicativo por aplicativos recentes. Então, lembre-se do serviço. Mas START_REDELIVER_INTENTnunca liguei novamente. Por quê?
Asif Mushtaq
@IlyaGazman Eu discordo respeitosamente. Parado e morto são duas palavras muito diferentes. Esta resposta explica o problema corretamente de maneira simples e direta.
NoHarmDan 13/11/19
23

A documentação START_STICKYe START_NOT_STICKYé bastante direta.

START_STICKY:

Se o processo deste serviço for interrompido enquanto é iniciado (depois de retornar onStartCommand(Intent, int, int)), deixe-o no estado iniciado, mas não retenha essa intenção entregue. Mais tarde, o sistema tentará recriar o serviço. Porque está no estado iniciado , ele garantirá a chamada onStartCommand(Intent, int, int) após a criação da nova instância de serviço; se não houver nenhum comando de inicialização pendente a ser entregue ao serviço, ele será chamado com um objeto de intenção nula, portanto, verifique isso.

Esse modo faz sentido para itens que serão explicitamente iniciados e parados para execução por períodos arbitrários, como um serviço executando a reprodução de música de fundo.

Exemplo: Amostra de Serviço Local

START_NOT_STICKY:

Se o processo desse serviço for interrompido enquanto é iniciado (após retornar de onStartCommand(Intent, int, int))e não houver novas intenções de entrega a serem entregues a ele, retire o serviço do estado iniciado e não o recrie até uma futura chamada explícita para Context.startService(Intent). não receberá uma onStartCommand(Intent, int, int)chamada com um nullIntent porque não será reiniciado se não houver Intents pendentes para entregar.

Esse modo faz sentido para coisas que desejam fazer algum trabalho como resultado do início, mas pode ser parado quando estiver sob pressão de memória e será explicitamente iniciado novamente mais tarde para realizar mais trabalho. Um exemplo desse serviço seria aquele que pesquisava dados de um servidor: ele poderia agendar um alarme para pesquisar a cada Nminuto, fazendo com que o alarme iniciasse seu serviço. Quando onStartCommand(Intent, int, int)é chamado do alarme, ele agenda um novo alarme para N minutos depois e gera um thread para fazer sua rede. Se o processo for interrompido durante a verificação, o serviço não será reiniciado até o alarme disparar.

Exemplo: ServiceStartArguments.java

Marvin Pinto
fonte
sem sorte pessoal .. Não pude relacionar a documentação na palavra do leigo. Eu gostaria de me relacionar com um cenário em tempo real. Eu gostaria de mostrar um exemplo no dispositivo. para que eles possam entender mais facilmente.
Prago
para START_STICKY e START_NOT_STICKY onStartCommand (), serão executados apenas uma vez e sairão dela. Passei pelo exemplo que você apontou, mas minha dúvida é quantas vezes o onStartCommand () será executado. se eu refazer START_STICKY e ainda tentar recriar o serviço, o serviço executará onStartCommand?
Prag # 3/12
o que acontece com a atividade quando o serviço é recriado? A atividade também é recriada?
Ransh 17/05
Eu acho que nós nunca saberemos
Denny