Fala galera, hoje
falaremos sobre serviços no android, mais especificamente da classe Service.
A classe Service é utilizada
para executar um serviço em segundo plano, por vezes vinculado a algum processo
que deve executar por tempo indetermidado e tem um alto consumo de recursos(Memória
e CPU); Um serviço pode ser
utilizado também para criar aplicações executadas em segundo plano sem a
necessidade de exibir uma interface ao usuário.
Tipos
de Serviço
Existem dois tipos
de serviço:
- Started (unbounded:ilimitado): são serviços iniciados por outros componentes (activities, broadcasts, etc.) através dos métodos startService(). Após iniciado o serviço pode continuar executando indefinidamente.
- Bounded(limitado): são serviços iniciados através do método bindService(). Este tipo de serviço interage com outros componentes através de uma interface cliente-servidor, pode inclusive ocorrer entre diferentes processos (IPC-Interprocess Comunication). É executado enquanto possuir requisições a serem tratadas.
Cliclo
de Vida
O ciclo de vida de um serviço é análogo ao de uma
Activity, porém um pouco mais simples:
![]() |
|
Iniciando e Parando um
Serviço
Para iniciar um
serviço é necessário, primeiramente, criar uma subclasse de android.app.Service
e configurar o AndroidManifest.xml, como todas as outras classes do Android,
usanto uma tag <sevice>:
<service
android:name=".HelloService"/>
E para iniciar basta
chamar o método startService(intent);
startService(new
Intent(this, HelloService.class));
Se preferir disparar
o serviço por uma ação utilize a tag <intente-filter>:
<service
android:name=".HelloService">
<intent-filter>
<action
android:name="ACAO_PARA_INICIAR_O_SERVICE"/>
<category
android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
Então poderíamos iniciar
o serviço com o seguinte código:
startService(new
Intent(“ACAO_PARA_INICIAR_O_SERVICE”));
O método startService(intent) inicia um serviço que fica executando por tempo indetermidado e vai continuar executando mesmo se o usuário sair da aplicação, ou seja, o serviço é independente da activity.
Depois de iniciado existem duas maneiras de parar um serviço, a primeira é chamar o método stopService(intent) com a mesma intent que foi utilizada para iniciá-lo. A segundo é o próprio serviço se encerrar com o método stopSelf().
Exemplo Prático
Agora vamos partir para prática e criar o projeto HelloService no Android Studio.
Como dito anteriormente para criar um serviço é preciso criar uma subclasse de android.app.Service e implementar obrigatóriamente o método IBinder onBind(intent). Podem ser também implementados de forma opcional os métodos onCreate(), onStartCommand(intent, flags, startId) e onDestroy() que fazem parte do ciclo de vida da classe Service.
HelloService.class
import com.codigosandroid.utils.utils.LogUtil;
import com.codigosandroid.utils.utils.NotificationUtil;
public class HelloService extends Service {
private static
final int MAX = 10;
private static
final String TAG = "codigos_android";
protected int
count;
private boolean
running;
@Nullable
@Override
public IBinder
onBind(Intent intent) {
// null aqui
porque não queremos interagir com o serviço(veremos um exemplo disso depois)
return null;
}
@Override
public void onCreate()
{
super.onCreate();
LogUtil.debug(TAG, "HelloService.onCreate() - Service
criado");
}
@Override
public int
onStartCommand(Intent intent, int flags, int startId) {
LogUtil.debug(TAG, "HelloService.onStartCommand() - Service
iniciado: " + startId);
count = 0;
/* Método
chamado depois do onCreate(), logo depois de iniciaro serviço
* O parâmetro
startId representa o identificador deste serviço */
running =
true;
// Deleta para
uma thread
new
WorkerThread().start();
// Chama a
implementação da superclasse
return
super.onStartCommand(intent, flags, startId);
}
// Thread que faz
o trabalho pesado
class WorkerThread
extends Thread {
@Override
public void
run() {
try {
while
(running && count < MAX){
//
Simula algum processamento
Thread.sleep(1000);
LogUtil.debug(TAG, "HelloService executando... " + count);
count++;
}
LogUtil.debug(TAG, "HelloService fim.");
} catch
(InterruptedException e) {
LogUtil.error(TAG, e.getMessage(), e);
} finally
{
// Auto-Encerra o serviço se o
contador chegou a 10
stopSelf();
//
Cria uma notificação para avisar o usuário que terminou.
Context context = HelloService.this;
Intent
intent = new Intent(context, MainActivity.class);
NotificationUtil.create(context, 1, intent, R.mipmap.ic_launcher,
"HelloService", "Fim do serviço.");
}
}
}
@Override
public void
onDestroy() {
super.onDestroy();
/* Ao encerrar
o serviço, altere o flag para a thread parar (isto é importante para encerrar
a thread caso
alguém tenha chamado o stopService(intent) */
running =
false;
LogUtil.debug(TAG, "HelloService.onDestroy() - Service
destruído");
}
}
Para o código compilar importe a classe NotificationUtil da biblioteca com.github.developermobile:utils:1.1.2. Feito isso configura o serviço no arquivo manifesto:
AndroidManifest.xml
<application..>
<activity android:name=".MainActivity">
<itent-filter>
<action android:name="android.itent.action.MAIN">
<category android:name="android.intent.category.LAUNCHER">
</intent-filter>
</activity>
<service android:name=".HelloService"/>
</application>
Para mostrar como inciar o serviço vamos criar uma activity com os botões start e stop:
/res/layout/activity_main.xml:
<LinearLayou... android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Exemplo de serviço, verifique os logs no
LogCat." />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start"
android:onClick="onClickStart"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stop"
android:onClick="onClickStop"/>
</LinearLayout>
No código da activity implemente os métodos que tratam os eventos dos botões para iniciar e parar o serviço, note que a mesma intent utilizada para iniciar o serviço é usada para pará-lo.
MainActivity.class
public class MainActivity extends BaseActivity {
public static final Class<? extends Service> CLS = HelloService.class;
@Override
protected void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void
onClickStart(View view) {
startService(new Intent(this, CLS));
}
public void
onClickStop(View view) {
stopService(new
Intent(this, CLS));
NotificationUtil.cancell(this, 1);
}
}
Feito isso excute o projeto e clique no botão Start para iniciar o serviço. O resultado da execução você pode conferir no LogCat que deve mostrar as seguintes mensagens:
02-07 13:16:25.142 4430-4430/com.codigosandroid.helloservice D/codigos_android: HelloService.onCreate() - Service criado
02-07 13:16:25.142 4430-4430/com.codigosandroid.helloservice D/codigos_android: HelloService.onStartCommand() - Service iniciado: 1
02-07 13:16:26.146 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 0
02-07 13:16:27.148 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 1
02-07 13:16:28.150 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 2
02-07 13:16:29.152 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 3
02-07 13:16:30.156 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 4
02-07 13:16:31.158 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 5
02-07 13:16:32.159 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 6
02-07 13:16:33.161 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 7
02-07 13:16:34.162 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 8
02-07 13:16:35.164 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 9
02-07 13:16:35.164 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService fim.
02-07 13:16:35.170 4430-4430/com.codigosandroid.helloservice D/codigos_android: HelloService.onDestroy() - Service destruído
02-07 13:16:25.142 4430-4430/com.codigosandroid.helloservice D/codigos_android: HelloService.onStartCommand() - Service iniciado: 1
02-07 13:16:26.146 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 0
02-07 13:16:27.148 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 1
02-07 13:16:28.150 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 2
02-07 13:16:29.152 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 3
02-07 13:16:30.156 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 4
02-07 13:16:31.158 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 5
02-07 13:16:32.159 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 6
02-07 13:16:33.161 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 7
02-07 13:16:34.162 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 8
02-07 13:16:35.164 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService executando... 9
02-07 13:16:35.164 4430-4508/com.codigosandroid.helloservice D/codigos_android: HelloService fim.
02-07 13:16:35.170 4430-4430/com.codigosandroid.helloservice D/codigos_android: HelloService.onDestroy() - Service destruído
Observe que o próprio serviço encerrou seu processo chamando o método stopSelf();
Apesar de acompanhar a execução do serviço pelo LogCat, você pode ver na imagem abaixo a notificação criada quando o serviço termina por conta própria, ou seja, quando o contador chega a 9:
Deixar o serviço executando e depois sair de uma tela:
O que acontece com o exemplo que criamos se logo depois de iniciarmos o serviço o usuário sair da tela? A resposta é que a activity seria destruída, mas o serviço não. Ele continuaria executando em segundo plano automaticamente. Para pará-lo basta iniciar a activity novamente e clicar no botão Stop ou esperar que o serviço termine.
Nota: No projeto deste tópico foi utilizado uma dependência para a notificação que informa o fim do serviço, posteriormente, ao fim desta série sobre a classe Service farei um tópico sobre a classe que cria essas notificações:a classe Notification.
Nota: No projeto deste tópico foi utilizado uma dependência para a notificação que informa o fim do serviço, posteriormente, ao fim desta série sobre a classe Service farei um tópico sobre a classe que cria essas notificações:a classe Notification.
Link do repositório com os projetos do blog incluindo nosso exemplo de Service: