Upload
others
View
9
Download
0
Embed Size (px)
Citation preview
Serviços
Serviços
Aplicações que executam, em geral, processos longos em background desprovidos de interface.
Usado para executar tarefas em segundo plano
Estas tarefas não possuem um tempo definido de execução (podendo ser demoradas)
Não deve iniciar activities: use notificações
Por padrão, é executado na Thread principal da aplicação host.
pode ser configurado para que o serviço inicie outras threads quando é chamado evitando assim que a interface trave durante uma execução que consuma muito processamento.
Manifesto
Para criar um serviço é preciso declarar o nome da
classe no Manifest.
Configuração no AndroidManifest.xml <application ... >
<service android:name="ServiceName">
<intent-filter>
<action android:name="com.example.serviceapp.ACTION" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
</application>
O serviço pode ser utilizado por qualquer aplicação
através de um Intent.
3
Se o serviço for útil apenas para a aplicação que o
contém, então é preciso explicitar que o serviço é
privado no Manifest. <application ... >
<service android:name="ServiceName">
android:exported ="false "
<intent-filter>
<action android:name="com.example.serviceapp.ACTION" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
</application>
Caso se queira iniciar o serviço de outra aplicação sem um
<intent-filter> deve-se usar android:exported="true"
Manifesto
4
Formas de iniciar um serviço
Pode ser iniciado de dentro de activity, broadcast
receiver ou outro serviço
Duas formas:
Desacoplado: serviço é iniciado e fica independente do
contexto (activity, receiver ou serviço) chamador
Com conexão: serviço é iniciado, retorna uma interface de
acesso e fica associado ao contexto chamador. Usado quando
precisa-se “conversar” com o serviço.
Métodos para inicialização (classe Context)
5
Método Descrição
startService(Intent) Inicia um serviço desacoplado
bindService(Intent, ServiceConnection,
flags)
Inicia um serviço conectado. O segundo
parâmetro é um objeto com métodos
callbacks para notificar conexão e
desconexão
Classe Service
Para se criar um serviço é preciso implementar uma extensão da classe Service e sobrescrever alguns métodos de callback.
onStartCommand() : inicia um serviço indefinidamente. O serviço apenas termina quando o método stopSelf() é executado a partir do próprio serviço ou quando o método stop-Service() é executado a partir de outra aplicação.
onBind() - chamado pelo sistema para associar o serviço a uma aplicação. Ele deve prover uma interface de comunicação entre ambos. Deve ser implementado. Se o serviço não for projetado para suportar Bind então o método onBind deve devolver null.
onCreate() - chamado pelo sistema no momento da criação do serviço e pode ser utilizado para realizar pré configurações.
onDestroy() - chamado pelo sistema quando o serviço for destruído e pode ser utilizado para liberar recursos utilizados.
Classe Service
7
Classe Service
O método onStartCommand() devolve um inteiro. Este valor indica como o sistema deve continuar o serviço caso o sistema o mate. Existem 3 valores possíveis:
START_NOT_STICKY - Não reinicia o serviço a menos que hajam Intents a serem entregues;
START_STICKY - Reinicia o serviço mas não continua a partir do Intent que estava em execução mas apenas para os que estavam pendentes;
START_REDELIVER_INTENT - Reinicia o serviço retomando a partir do Intent que estava em execução.
Ciclo de vida de um serviço
9
Compatibilidade com versões
anteriores // Método onStart antigo que é chamado nas
// plataformas anteriores a 2.0
@Override
public void onStart(Intent intent, int startId) {
processaStart(intent);
}
// Método chamado a partir da plataforma 2.0
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
processaStart(intent);
// Retorne isto para que o serviço rode até ser
// explicitamente terminado
return START_STICKY;
}
// Método para onde onStart e onStartCommand converge
protected void processaStart (Intent intent) {
// Processa independente de versão de plataforma
}
10
Inicialização de serviços desacoplados
Método startService(Intent)
Inicia o serviço determinado pela intent.
O serviço roda independente do chamador e por tempo indeterminado
Se o contexto chamador terminar o serviço continua rodando normalmente
Pode ser chamado inúmeras vezes
Apenas na primeira o callback onCreate() é chamado
O método onStart/onStartCommand sempre é chamado
Método stopService(Intent)
Termina o serviço chamando onDestroy()
Não importa quantas vezes startService() foi chamado, uma única chamada a este encerra o serviço
11
Como e quando terminar serviços
Método stopSelf()
Chamar quando serviço terminar o
processamento
Boa prática para evitar consumo de bateria
Caso queira que o serviço volte a executar
de forma automática no futuro usar
AlarmManager (em breve)
12
Service e Threads
A thread que executa o serviço é a thread
principal da aplicação host.
Caso o serviço ocupe muito processamento é
preciso que o serviço utilize uma nova thread
evitando assim travamentos na interface.
A seguir, a classe do serviço foi modificada para
executar sua tarefa em uma thread separada.
Service e Threads public class ExampleService extends Service {
private Looper mServiceLooper ;
private ServiceHandler mServiceHandler ;
// Handler que executa de fato a tarefa do serviço
// em uma thread separada
private final class ServiceHandler extends Handler {
public ServiceHandler (Looper looper) {
super(looper);
}
@Override
public void handleMessage (Message msg) {
// Implementacao da tarefa do servico
...
// Parando explicitamente o servico
stopSelf(msg.arg1);
}
}
Service e Threads @Override
public void onCreate () {
// Criando a thread responsavel pela execucao da tarefa
HandlerThread thread = new HandlerThread ("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND );
thread.start ();
// Obtendo o Looper da thread e passando como parametro para o Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public int onStartCommand (Intent intent,int flags,int startId) {
Toast.makeText(this,"service starting",Toast.LENGTH_SHORT).show();
// Para cada chamada ao servico enfileiramos uma tarefa no Handler
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// Se o servico morrer a partir deste ponto , reiniciar
return START_STICKY ;
}
@Override
public IBinder onBind (Intent intent) {
// sem suporte a Binding
return null ;
}
@Override
public void onDestroy () {
Toast.makeText(this,"service done",Toast.LENGTH_SHORT).show();
}
}
Service
O método onStartCommand() pode ser chamado pelo sistema diversas vezes, uma para cada requisição da aplicação.
Cada uma vem acompanhada de um id (startId).
Se ao final de uma execução o método stopSelf() for chamado enquanto uma outra requisição está sendo executada, o serviço terminaria sem completar a segunda execução.
Para evitar isto, o método stopSelf() pode receber um inteiro que representa o id da requisição que terminou.
Se o id for igual ao da última requisição o serviço termina, caso contrário ele continua a executar até que as requisições acabem.
Service
É comum implementar serviços que utilizem sua
própria thread para executar as tarefas
requisitadas.
Desta forma, o framework fornece uma extensão
da classe Service que simplifica a criação de
serviços como o mostrado anteriormente.
O código a seguir implementa um serviço que se
comporta como o exemplo anterior utilizando a
classe IntentService.
IntentService public class ExampleService extends IntentService {
/**
* O construtor é obrigatório e deve chamar o construtor da
* superclasse passando o nome da Thread worker
*/
public ExampleService () {
super (" ExampleService ");
}
/**
* Este método é chamado pela IntentService a partir de um worker
* Thread e recebe o Intent que iniciou o serviço . Quando o método
* termina o IntentService para o serviço .
*/
@Override
protected void onHandleIntent ( Intent intent ) {
// Implementação da tarefa do serviço
} }
Não é necessário se preocupar em parar o serviço
Iniciando um serviço
basta criar um intent e passá-lo como
parâmetro ao método startService()
Intent intent = new Intent (this,ExampleService.class );
startService ( intent );
Exercício: Service para
donwnload Crie um projeto Android chamado TesteService e
o nome da activity deve ser MainActivity.
Adicione um botão no tela de MainActivity.
Crie a classe DownloadService comoa seguir:
MainActivity