Um Service
é
componente de aplicativo que pode realizar
operações de longa duração em segundo plano. Ele não fornece uma interface do usuário. Uma vez
iniciado, um serviço pode continuar em execução por algum tempo, mesmo após o usuário mudar para outro
para o aplicativo. Além disso, um componente pode se vincular a um serviço para interagir com ele e até mesmo
comunicação entre processos (IPC). Por exemplo, um serviço pode lidar com transações de rede, reproduzir
músicas, execute E/S de arquivos ou interaja com um provedor de conteúdo, tudo em segundo plano.
Cuidado:um serviço é executado na linha de execução principal da hospedagem. processo o serviço não cria a própria linha de execução e não em um processo separado, a menos que você especifique o contrário. Execute todas as operações de bloqueio uma linha de execução separada dentro do serviço para evitar que o Erros "Não está respondendo" (ANR).
Tipos de serviços
Veja os três tipos diferentes de serviços:
- Primeiro plano
-
Um serviço em primeiro plano realiza alguma operação que é perceptível para as usuário. Por exemplo, um app de áudio usaria um serviço em primeiro plano para reproduzir uma faixa de áudio. Os serviços em primeiro plano precisam exibir uma Notification. Serviços em primeiro plano continuam em execução mesmo quando o usuário não está interagindo com o app.
Ao usar um serviço em primeiro plano, mostre uma notificação para que os usuários estão ativamente cientes de que o serviço está em execução. Esta notificação não pode ser dispensado, a menos que o serviço seja interrompido ou removido do primeiro plano.
Saiba como configurar serviços em primeiro plano na sua app.
Observação: o A API WorkManager oferece uma maneira flexível de agendar tarefas e é ser capaz de executar esses jobs como serviços em primeiro plano, se necessário. Em muitos casos, usar É preferível usar o WorkManager do que usar os serviços em primeiro plano diretamente.
- Contexto
- Um serviço em segundo plano realiza uma operação que não é notada diretamente pelas
o usuário. Por exemplo, se um app usou um serviço para compactar o armazenamento,
que normalmente seria um serviço em segundo plano.
Observação:se o app for direcionado ao nível 26 da API ou mais recente, o sistema vai impor restrições à execução em segundo plano serviços quando o próprio app não está em primeiro plano. Na maioria situações, por exemplo, você não deve acessar informações de localização do segundo plano. Em vez disso, programar tarefas usando WorkManager.
- Vinculado
- Um serviço é vinculado quando um componente do aplicativo o chama chamando
bindService()
. Um serviço vinculado oferece um serviço cliente-servidor que permite que os componentes interajam com o serviço, enviem solicitações, recebam resultados e até mesmo em processos com comunicação entre processos (IPC). Um serviço vinculado é executado somente desde que outro componente do aplicativo esteja vinculado a ele. Vários componentes podem se vincular serviço de uma só vez, mas quando todos os vínculos forem desvinculados, o serviço será destruído.
Embora esta documentação geralmente discuta serviços iniciados e vinculados separadamente,
seu serviço pode funcionar de ambas as formas: ele pode ser iniciado (para funcionar indefinidamente) e também permitir
vinculação. Basta implementar alguns métodos de callback: onStartCommand()
para permitir que os componentes a iniciem e onBind()
para permitir a vinculação.
Independentemente de o serviço ser iniciado, vinculado ou ambos, qualquer componente do aplicativo
podem usar o serviço (mesmo de um aplicativo separado) da mesma forma que qualquer componente.
uma atividade, iniciando com uma Intent
. No entanto, é possível declarar
o serviço como privado no arquivo de manifesto e bloqueia o acesso de outros aplicativos.
Isso é discutido com mais detalhes na seção Como declarar o serviço no
manifesto do app.
Como escolher entre um serviço e um thread
Um serviço é simplesmente um componente que pode ser executado em segundo plano, mesmo quando o usuário não está interagir com o aplicativo. Por isso, só crie um serviço se você quiser precisam.
Se você precisar realizar um trabalho fora da linha de execução principal, mas apenas enquanto o usuário estiver interagindo
com seu aplicativo, crie uma nova linha de execução no contexto de outro aplicativo
componente. Por exemplo, se você quiser ouvir alguma música, mas apenas enquanto sua atividade estiver em execução,
crie uma conversa em onCreate()
,
comece a executá-lo em onStart()
,
e interrompê-lo em onStop()
.
Considere também usar pools de linhas de execução e executores do pacote java.util.concurrent
ou corrotinas Kotlin em vez da
classe Thread
. Consulte a
Documento Linhas de execução no Android para mais informações sobre
movendo a execução para linhas de execução em segundo plano.
Lembre-se de que, se você usar um serviço, ele ainda será executado na linha de execução principal do aplicativo padrão. Você ainda deve criar um novo thread dentro do serviço caso ele execute tarefas intensas ou operações de bloqueio.
Noções básicas
Para criar um serviço, você precisa criar uma subclasse de Service
ou usar uma
das subclasses existentes. Na implementação, é preciso substituir alguns métodos de callback que
lidam com aspectos-chave do ciclo de vida do serviço e fornecem um mecanismo que permite aos componentes
vincular ao serviço, se apropriado. Esses são os métodos de callback mais importantes que você deve
substituir:
onStartCommand()
- O sistema invoca esse método chamando
startService()
quando outro componente (como uma atividade) solicita que o serviço seja iniciado. Quando este método é executado, o serviço é iniciado e pode ser executado no plano de fundo indefinidamente. Se você implementar isso, será sua responsabilidade interromper o serviço quando seu trabalho seja concluído chamandostopSelf()
oustopService()
. Se você só quiser fornecer a vinculação, precisam implementar esse método. onBind()
- O sistema invoca esse método chamando
bindService()
quando outro componente quer se vincular ao serviço (por exemplo, para realizar RPC). Na sua implementação desse método, você precisa fornecer uma interface que os clientes use para se comunicar com o serviço retornando umIBinder
. Você sempre deve implementar esse método; No entanto, se não quiser permitir a vinculação, você deverá retornar nulo. onCreate()
- O sistema invoca esse método para executar procedimentos únicos de configuração quando o serviço é
criada inicialmente (antes de chamar
onStartCommand()
ouonBind()
). Se o serviço já estiver em execução, esse método não será chamou. onDestroy()
- O sistema invoca esse método quando o serviço não é mais usado e está sendo destruído. Seu serviço deve implementar isso para limpar todos os recursos, como threads, registrados ouvintes ou receptores. Essa é a última chamada que o serviço recebe.
Se um componente iniciar o serviço chamando startService()
(o que resulta em uma chamada para onStartCommand()
), o serviço
continua em execução até ser interrompido com stopSelf()
ou outro
interrompe essa ação chamando stopService()
.
Se um componente chamar
bindService()
para criar o serviço e onStartCommand()
não é chamado, o serviço é executado
enquanto o componente estiver vinculado a ela. Depois que o serviço for desvinculado de todos os clientes,
pelo sistema.
O sistema Android só interrompe um serviço quando a memória está baixa e precisa recuperar o sistema
recursos para a atividade com o foco do usuário. Se o serviço estiver vinculado a uma atividade que tenha usuários
foco, é menos provável que seja morto; Se o serviço for declarado para executar em primeiro plano, ele raramente será encerrado.
Se o serviço for iniciado e for de longa duração, o sistema abaixará sua posição
na lista de tarefas em segundo plano ao longo do tempo, e o serviço se torna altamente suscetível a
Eliminação: se o serviço for iniciado, você deve projetá-lo para lidar normalmente com reinicializações.
pelo sistema. Se o sistema eliminar seu serviço, ele reiniciará assim que os recursos ficarem
disponível, mas isso também depende do valor retornado de onStartCommand()
. Para mais informações
sobre quando o sistema pode destruir um serviço, consulte a seção Processos e linhas de execução
documento.
Nas seções a seguir, você vai aprender a criar o
startService()
e
métodos do serviço bindService()
, além de como usá-los
usando outros componentes do aplicativo.
Declaração de serviço no manifesto
Você precisa declarar todos os serviços no arquivo do arquivo de manifesto, assim como para atividades e outros componentes.
Para declarar o serviço, adicione um elemento <service>
.
como filho da <application>
. Confira um exemplo:
<manifest ... > ... <application ... > <service android:name=".ExampleService" /> ... </application> </manifest>
Consulte o elemento <service>
para mais informações sobre como declarar o serviço no manifesto.
Há outros atributos que podem ser incluídos no elemento <service>
para
definem propriedades como as permissões necessárias para iniciar o serviço e o processo
em que o serviço deve ser executado. O android:name
é o único atributo obrigatório. Ele especifica o nome da classe do serviço. Depois
você publicar seu aplicativo, deixe esse nome inalterado para evitar o risco de corrupção
devido à dependência de intents explícitas para iniciar ou vincular o serviço (leia a postagem do blog, Coisas
Isso não pode mudar).
Cuidado: para garantir a segurança do seu app, use sempre uma propriedade
uma intent explícita ao iniciar uma Service
e não declarar filtros de intent para
seus serviços. O uso de um intent implícito para iniciar um serviço representa um risco de segurança porque não é possível
ter certeza sobre o serviço que responde à intent e o usuário não puder ver qual serviço
começa. No Android 5.0 (nível 21 da API) e versões mais recentes, o sistema gera uma exceção quando você chama
bindService()
com uma intent implícita.
Para garantir que o serviço esteja disponível apenas para seu app,
incluindo o android:exported
e defini-lo como false
. Isso efetivamente impede que outros apps iniciem o
serviço, mesmo com uma intent explícita.
Observação:
Os usuários podem ver quais serviços estão sendo executados no dispositivo deles. Se eles virem
um serviço que não reconhecem ou em que não confiam, poderão interrompê-lo. Em
para evitar que seu serviço seja interrompido acidentalmente pelos usuários, é necessário
para adicionar
android:description
ao atributo
<service>
no manifesto do app. Na descrição,
forneça uma frase curta explicando o que o serviço faz e quais benefícios
que ele oferece.
Criação de um serviço iniciado
Um serviço iniciado é aquele que outro componente inicia chamando startService()
, o que resulta em uma chamada para o
onStartCommand()
.
Quando um serviço é iniciado, ele tem um ciclo de vida que não depende
que a iniciou. O serviço pode ser executado em segundo plano indefinidamente, mesmo que
o componente que o iniciou é destruído. Dessa forma, o serviço deve ser interrompido quando o job
é concluída chamando stopSelf()
, ou outro componente pode
interrompa-o chamando stopService()
.
Um componente de aplicativo, como uma atividade, pode iniciar o serviço chamando startService()
e transmitindo um Intent
.
que especifica o serviço e inclui os dados a serem usados pelo serviço. O serviço recebe
este Intent
no método onStartCommand()
.
Por exemplo, imagine que uma atividade precise salvar alguns dados em um banco de dados on-line. A atividade
pode iniciar um serviço complementar e enviar a ele os dados a serem salvos transmitindo uma intent para startService()
. O serviço recebe a intent em onStartCommand()
, se conecta à Internet e executa a
transação do banco de dados. Quando a transação é concluída, o serviço é interrompido e
destruídos.
Cuidado:um serviço é executado no mesmo processo que o aplicativo. em que ele é declarado e na linha de execução principal do aplicativo por padrão. Se o serviço realiza operações intensivas ou de bloqueio enquanto o usuário interage com uma atividade do mesmo o serviço retarda o desempenho da atividade. Para não afetar o aplicativo desempenho, inicie uma nova linha de execução dentro do serviço.
A classe Service
é a base
para todos os serviços. Ao estender essa classe, é importante criar uma nova linha de execução em que
o serviço pode concluir todo o trabalho; o serviço usa o thread principal do aplicativo
padrão, o que pode retardar o desempenho de qualquer atividade que seu aplicativo esteja executando.
O framework do Android também fornece o IntentService
de Service
que usa uma
linha de execução de worker para processar todas as solicitações de inicialização, uma de cada vez. Usar esta classe não é
recomendado para novos apps, já que não funcionará bem a partir do Android 8 Oreo, devido às
introdução dos limites de execução em segundo plano.
Além disso, ele foi descontinuado no Android 11.
Você pode usar JobIntentService como
substituto de IntentService
, que é compatível com versões mais recentes do Android.
As seções a seguir descrevem como implementar seu próprio serviço personalizado, mas você deve considere usar o WorkManager na maioria dos casos. Consulte o guia para processamento em segundo plano no Android. para ver se há uma solução que atenda às suas necessidades.
Extensão da classe Service
É possível estender a classe Service
para lidar com cada intent recebida. Veja como pode ser uma implementação básica:
Kotlin
class HelloService : Service() { private var serviceLooper: Looper? = null private var serviceHandler: ServiceHandler? = null // Handler that receives messages from the thread private inner class ServiceHandler(looper: Looper) : Handler(looper) { override fun handleMessage(msg: Message) { // Normally we would do some work here, like download a file. // For our sample, we just sleep for 5 seconds. try { Thread.sleep(5000) } catch (e: InterruptedException) { // Restore interrupt status. Thread.currentThread().interrupt() } // Stop the service using the startId, so that we don't stop // the service in the middle of handling another job stopSelf(msg.arg1) } } override fun onCreate() { // Start up the thread running the service. Note that we create a // separate thread because the service normally runs in the process's // main thread, which we don't want to block. We also make it // background priority so CPU-intensive work will not disrupt our UI. HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND).apply { start() // Get the HandlerThread's Looper and use it for our Handler serviceLooper = looper serviceHandler = ServiceHandler(looper) } } override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show() // For each start request, send a message to start a job and deliver the // start ID so we know which request we're stopping when we finish the job serviceHandler?.obtainMessage()?.also { msg -> msg.arg1 = startId serviceHandler?.sendMessage(msg) } // If we get killed, after returning from here, restart return START_STICKY } override fun onBind(intent: Intent): IBinder? { // We don't provide binding, so return null return null } override fun onDestroy() { Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show() } }
Java
public class HelloService extends Service { private Looper serviceLooper; private ServiceHandler serviceHandler; // Handler that receives messages from the thread private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { // Normally we would do some work here, like download a file. // For our sample, we just sleep for 5 seconds. try { Thread.sleep(5000); } catch (InterruptedException e) { // Restore interrupt status. Thread.currentThread().interrupt(); } // Stop the service using the startId, so that we don't stop // the service in the middle of handling another job stopSelf(msg.arg1); } } @Override public void onCreate() { // Start up the thread running the service. Note that we create a // separate thread because the service normally runs in the process's // main thread, which we don't want to block. We also make it // background priority so CPU-intensive work doesn't disrupt our UI. HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); // Get the HandlerThread's Looper and use it for our Handler serviceLooper = thread.getLooper(); serviceHandler = new ServiceHandler(serviceLooper); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); // For each start request, send a message to start a job and deliver the // start ID so we know which request we're stopping when we finish the job Message msg = serviceHandler.obtainMessage(); msg.arg1 = startId; serviceHandler.sendMessage(msg); // If we get killed, after returning from here, restart return START_STICKY; } @Override public IBinder onBind(Intent intent) { // We don't provide binding, so return null return null; } @Override public void onDestroy() { Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); } }
O código de exemplo processa todas as chamadas recebidas em onStartCommand()
.
e publica o trabalho em um Handler
executado em uma linha de execução em segundo plano. Ele funciona como um IntentService
e processa todas as solicitações em série, uma após a outra.
Você pode mudar o código para executar o trabalho em um pool de linhas de execução, por exemplo, se quiser executar várias solicitações simultaneamente.
O método onStartCommand()
precisa retornar uma
inteiro. O número inteiro é um valor que descreve como o sistema deve continuar o serviço na
evento que o sistema o eliminará. O valor de retorno
de onStartCommand()
precisa ser um dos seguintes
constantes:
START_NOT_STICKY
- Se o sistema eliminar o serviço após o retorno de
onStartCommand()
, não recrie o serviço, a menos que haja intents a serem entregues. Essa é a opção mais segura para evitar executar seu serviço quando não for necessário e quando o aplicativo pode simplesmente reiniciar qualquer job não concluído. START_STICKY
- Se o sistema eliminar o serviço após o retorno de
onStartCommand()
, recrie o serviço e chameonStartCommand()
, mas não reenvie a última intent. Em vez disso, o sistema chamaonStartCommand()
com uma intent nula, a menos que haja intents pendentes para iniciar o serviço. Nesse caso, para que as intents sejam entregues. Isso é adequado para players de mídia (ou serviços semelhantes) que não são que executam comandos, mas que ficam em execução indefinidamente e aguardando um job. START_REDELIVER_INTENT
- Se o sistema eliminar o serviço após o retorno de
onStartCommand()
, recrie o serviço e chameonStartCommand()
com a última intent que foi entregue ao serviço. Quaisquer intents pendentes são entregues um de cada vez. Isso é adequado para serviços que são realizar ativamente um trabalho que deve ser retomado imediatamente, como o download de um arquivo.
Para mais detalhes sobre esses valores de retorno, consulte a referência vinculada documentação de cada constante.
Iniciar um serviço
Você pode iniciar um serviço a partir de uma atividade ou outro componente do aplicativo
transmitir um Intent
como startService()
ou startForegroundService()
. A
O sistema Android chama o método onStartCommand()
do serviço e transmite a ele o Intent
,
que especifica qual serviço iniciar.
Observação: caso seu app seja direcionado ao nível 26 da API ou mais recente, o sistema
impõe restrições ao uso ou à criação de serviços em segundo plano, a menos que o aplicativo
está em primeiro plano. Se um app precisar criar um serviço em primeiro plano,
o app precisa chamar startForegroundService()
. Esse método cria um serviço de segundo plano, mas a
indica ao sistema que o serviço se promoverá à
primeiro plano. Depois que o serviço é criado, ele precisa chamar o
startForeground()
em
cinco segundos.
Por exemplo, uma atividade pode iniciar o serviço de exemplo na seção anterior (HelloService
) usando uma intent explícita com startService()
, conforme mostrado aqui:
Kotlin
startService(Intent(this, HelloService::class.java))
Java
startService(new Intent(this, HelloService.class));
O método startService()
retorna imediatamente e
o sistema Android chama o método onStartCommand()
do serviço. Se o serviço ainda não estiver em execução, o sistema primeiro vai chamar onCreate()
e depois chamar
onStartCommand()
.
Se o serviço não fornecer vinculação, a intent entregue com startService()
será o único modo de comunicação entre o
componente do aplicativo e o serviço. No entanto, se você quiser que o serviço retorne um resultado,
o cliente que inicia o serviço pode criar um PendingIntent
para uma transmissão
(com getBroadcast()
) e entregá-lo ao serviço.
no Intent
que inicia o serviço. Assim, o serviço pode usar
para entregar um resultado.
Várias solicitações para iniciar o serviço resultam em diversas chamadas correspondentes ao serviço
onStartCommand()
: No entanto, apenas uma solicitação para interromper
o serviço (com stopSelf()
ou stopService()
) é necessário para interrompê-lo.
Interromper um serviço
Um serviço iniciado precisa gerenciar o próprio ciclo de vida. Ou seja, o sistema não para
destruir o serviço, a menos que ele precise recuperar a memória do sistema e o serviço
continua sendo exibido depois que onStartCommand()
é retornado. A
serviço precisa ser interrompido chamando stopSelf()
ou outra
pode interrompê-lo chamando stopService()
.
Ao solicitar a interrupção com stopSelf()
ou stopService()
, o sistema destruirá o serviço assim que
sempre que possível.
Se o serviço processa várias solicitações para onStartCommand()
ao mesmo tempo, não é recomendável interromper
serviço quando terminar de processar uma solicitação de inicialização, pois você pode ter recebido uma nova
start (interromper no final da primeira solicitação encerra a segunda). Para evitar
esse problema, use stopSelf(int)
para garantir que sua solicitação
interromper o serviço é sempre baseado na solicitação de inicialização mais recente. Ou seja, ao chamar stopSelf(int)
, você transmite o ID da solicitação de inicialização (o startId
).
entregue a onStartCommand()
) para a qual sua solicitação de interrupção
que correspondem. Assim, se o serviço receber uma nova solicitação de inicialização antes de você poder chamar stopSelf(int)
, o ID não corresponderá e o serviço não será interrompido.
Cuidado: para evitar o desperdício de recursos do sistema e o consumo
bateria, certifique-se de que seu aplicativo interrompa os serviços quando terminar de trabalhar.
Se necessário, outros componentes podem interromper o serviço chamando stopService()
. Mesmo que você ative a vinculação para o serviço,
interrompa o serviço por conta própria se ele receber uma chamada para onStartCommand()
.
Para mais informações sobre o ciclo de vida de um serviço, consulte a seção Gerenciamento do ciclo de vida de um serviço abaixo.
Como criar um serviço vinculado
Um serviço vinculado é aquele que permite que os componentes do aplicativo sejam vinculados chamando bindService()
para criar uma conexão de longa data.
Geralmente, ele não permite que os componentes a iniciem chamando startService()
.
Criar um serviço vinculado quando quiser interagir com ele nas atividades e outros componentes no seu aplicativo ou para expor algumas das funcionalidades do seu aplicativo à por outros aplicativos pela comunicação entre processos (IPC).
Para criar um serviço vinculado, implemente o método de callback onBind()
para retornar um IBinder
que
define a interface de comunicação com o serviço. Outros componentes do aplicativo podem chamar
bindService()
para recuperar a interface e
começar a chamar métodos no serviço. O serviço existe somente para servir o componente do aplicativo que
está vinculado a ele. Portanto, quando não há componentes vinculados ao serviço, o sistema o destrói.
Não é necessário interromper um serviço vinculado da mesma maneira que quando o serviço é
iniciado até onStartCommand()
.
Para criar um serviço vinculado, defina a interface que especifica como um cliente pode
se comunicar com o serviço. Essa interface entre o serviço
e um cliente precisa ser uma implementação do IBinder
e é isso que seu serviço precisa
retornar do método de callback onBind()
. Depois que o cliente receber o IBinder
, ele poderá começar
que interage com o serviço por meio dessa interface.
Vários clientes podem se vincular ao serviço por vez. Quando um cliente terminar de interagir
o serviço, ele chama unbindService()
para se desvincular.
Quando não houver clientes vinculados ao serviço, o sistema o eliminará.
Há várias maneiras de implementar um serviço vinculado, e a implementação é mais complicado do que um serviço iniciado. Por esses motivos, a discussão do serviço vinculado aparece em uma documento separado sobre Serviços vinculados.
Envio de notificações ao usuário
Quando um serviço está em execução, ele pode notificar o usuário sobre eventos usando notificações da barra de lanches ou notificações da barra de status.
Uma notificação snackbar é uma mensagem que aparece na superfície da janela atual por apenas uma momento antes de desaparecer. Uma notificação da barra de status fornece um ícone na barra de status com uma que o usuário pode selecionar para realizar uma ação (como iniciar uma atividade).
Normalmente, uma notificação da barra de status é a melhor técnica para usar quando um trabalho em segundo plano, como um download de arquivo foi concluído e o usuário agora pode realizar uma ação nele. Quando o usuário seleciona a notificação a partir da visualização expandida, a notificação pode iniciar uma atividade (por exemplo, para exibir o arquivo baixado).
Gerenciamento do ciclo de vida de um serviço
O ciclo de vida de um serviço é muito mais simples do que o de uma atividade. No entanto, é ainda mais preste muita atenção em como seu serviço é criado e destruído porque um serviço possa ser executado em segundo plano sem que o usuário esteja ciente.
O ciclo de vida do serviço, desde a criação até o término, pode seguir um destes dois caminhos:
- Um serviço iniciado
O serviço é criado quando outro componente chama
startService()
. O serviço é executado indefinidamente e precisa seja interrompido chamandostopSelf()
. Outro componente também pode interromper a o serviço chamandostopService()
. Quando o serviço é interrompido, o sistema o elimina. - Um serviço vinculado
O serviço é criado quando outro componente (um cliente) chama
bindService()
. Em seguida, o cliente se comunica com o serviço usando uma interfaceIBinder
. O cliente pode encerrar a conexão chamandounbindService()
: Vários clientes podem se vincular o mesmo serviço e, quando todos os vínculos forem desvinculados, o sistema o destruirá. O serviço não precisa ser interrompida.
Esses dois caminhos não são completamente separados. É possível se vincular a um serviço que já está
começou com startService()
. Por exemplo, é possível
inicie um serviço de música em segundo plano chamando startService()
com um Intent
que identifique a música a ser reproduzida. Depois,
possivelmente quando o usuário quiser exercer algum controle sobre o jogador ou obter informações sobre o
a música atual, uma atividade pode se vincular ao serviço chamando bindService()
. Em casos como esse, stopService()
ou stopSelf()
não interrompem o serviço até que todos os clientes sejam desvinculados.
Implementação dos callbacks do ciclo de vida
Assim como uma atividade, um serviço tem métodos de callback do ciclo de vida que podem ser implementados para monitorar mudanças no estado do serviço e realizar o trabalho nos momentos apropriados. O esqueleto a seguir serviço demonstra cada um dos métodos do ciclo de vida:
Kotlin
class ExampleService : Service() { private var startMode: Int = 0 // indicates how to behave if the service is killed private var binder: IBinder? = null // interface for clients that bind private var allowRebind: Boolean = false // indicates whether onRebind should be used override funonCreate
() { // The service is being created } override funonStartCommand
(intent: Intent?, flags: Int, startId: Int): Int { // The service is starting, due to a call to startService() return startMode } override funonBind
(intent: Intent): IBinder? { // A client is binding to the service with bindService() return binder } override funonUnbind
(intent: Intent): Boolean { // All clients have unbound with unbindService() return allowRebind } override funonRebind
(intent: Intent) { // A client is binding to the service with bindService(), // after onUnbind() has already been called } override funonDestroy
() { // The service is no longer used and is being destroyed } }
Java
public class ExampleService extends Service { int startMode; // indicates how to behave if the service is killed IBinder binder; // interface for clients that bind boolean allowRebind; // indicates whether onRebind should be used @Override public voidonCreate
() { // The service is being created } @Override public intonStartCommand
(Intent intent, int flags, int startId) { // The service is starting, due to a call tostartService()
return startMode; } @Override public IBinderonBind
(Intent intent) { // A client is binding to the service withbindService()
return binder; } @Override public booleanonUnbind
(Intent intent) { // All clients have unbound withunbindService()
return allowRebind; } @Override public voidonRebind
(Intent intent) { // A client is binding to the service withbindService()
, // after onUnbind() has already been called } @Override public voidonDestroy
() { // The service is no longer used and is being destroyed } }
Observação:diferentemente dos métodos de callback do ciclo de vida da atividade, você está não é necessário para chamar a implementação da superclasse desses métodos de callback.
![](https://developer.android.com/static/images/service_lifecycle.png?authuser=19&hl=pt)
Figura 2. Ciclo de vida do serviço. O diagrama à esquerda
mostra o ciclo de vida quando o serviço é criado com startService()
e o diagrama à direita mostra o ciclo de vida quando o serviço é criado
com bindService()
.
A figura 2 ilustra os métodos de callback tradicionais para um serviço. Apesar de a figura separar
e serviços criados por startService()
a partir de
criado por bindService()
, mantenha
em mente que qualquer serviço, independentemente de como ele tenha sido iniciado, pode permitir que os clientes se vinculem a ele.
um serviço que foi iniciado inicialmente com onStartCommand()
(por um cliente que chama startService()
);
ainda pode receber uma chamada para onBind()
(quando um cliente liga
bindService()
).
Ao implementar esses métodos, você pode monitorar esses dois loops aninhados do serviço ciclo de vida:
- Todo o ciclo de vida de um serviço ocorre entre o momento em que
onCreate()
é chamado e o momento em queonDestroy()
retorna. Como uma atividade, um serviço faz sua configuração inicialonCreate()
e libera todos os recursos restantes emonDestroy()
. Por exemplo, O serviço de reprodução de música pode criar a linha de execução em que a música é tocada emonCreate()
e, em seguida, interrompê-la emonDestroy()
.Observação: o
onCreate()
eonDestroy()
são chamados para todos os serviços, elas foram criadas porstartService()
oubindService()
. - O ciclo de vida ativo de um serviço começa com uma chamada para
onStartCommand()
ouonBind()
. Cada método recebe oIntent
que foi transmitido para ostartService()
ou obindService()
.Se o serviço for iniciado, o ciclo de vida ativo terminará ao mesmo tempo que todo o ciclo de vida terminar (o serviço ainda estará ativo mesmo após o retorno de
onStartCommand()
); Se o serviço estiver vinculado, o ciclo de vida ativo terminará quandoonUnbind()
retornar.
Observação: embora um serviço iniciado seja interrompido por uma chamada para
stopSelf()
ou stopService()
, não há um callback respectivo para o
serviço (não há callback onStop()
). A menos que o serviço esteja vinculado a um cliente,
o sistema a destrói quando o serviço é interrompido. onDestroy()
é o único callback recebido.
Para mais informações sobre como criar um serviço que forneça vinculação, consulte o documento Serviços vinculados,
que inclui mais informações sobre a onRebind()
método de callback na seção Gerenciar o ciclo de vida de
um serviço vinculado.