Threads, Handler, Looper e Message Queue: Parte 1 — Thread
--
Como desenvolvedores de apps Android, o tempo todo falamos sobre threads, sobre a main thread no Android (principalmente) e sobre vários outros temas envolvendo assincronísmo. Mas o que são threads, como elas funcionam e qual a sua relação com Handler, Looper e Message Queue? Te convido agora a começar a busca pelas respostas 🤔!
Threads
Uma thread é um “bloco” com instruções para serem executadas de maneira concorrente ao longo da vida de uma aplicação. A JVM permite uma aplicação ter múltiplas threads rodando de forma concorrente.
Cada thread pode ou não também ser marcada como daemon thread. Mas o que significa uma thread ser daemon? Significa que a execução da thread é interrompida quando a thread principal termina a sua execução. Caso existam threads não daemon sendo executadas, o processo continua ativo e executando, mesmo que a thread principal termine.
Veja a seguir a diferença de uma thread daemon para uma thread não-daemon:
- Thread.isDaemon = true
Output:
Podemos ver que a execução da thread foi finalizada, executando uma única vez o que tem dentro do bloco repeat
.
2. Thread.isDaemon = false (default)
Output:
Como podemos ver na imagem acima, a thread continua executando até finalizar por completo o seu trabalho.
Quando a JVM inicia, uma thread não-daemon é criada (a thread principal, main
). A JVM continua executando até que uma das seguintes situações ocorra:
- O método
exit
da classeRuntime
seja chamado; - Todas as threads não-daemon foram finalizadas, seja pelo término da sua execução ou pelo lançamento de uma exceção;
Criando Threads
Existem algumas formas de criar uma nova thread e colocá-la em execução:
- Criando uma instância da classe
Thread
passando umRunnable
em seu construtor:
2. Criando uma classe que herda Thread
:
Para executá-la, basta chamar MyCustomThread().start()
.
3. Criando uma classe que implementa a interface Runnable
e passando uma instância dela para uma thread executá-la:
Para executar: Thread(MyCustomThread()).start()
.
Main Thread no Android — Under the hood
Existe um pouco de mistério quando falamos da thread principal ou a famosa main thread no Android. Mas o que de fato é essa thread e onde ela é criada?
No pacote android.app
podemos encontrar a classe ActivityThread
. Ela será nosso foco nesta seção do post. Vamos ver o que o javadoc da classe nos diz sobre ela:
"This manages the execution of the main thread in an application process, scheduling and executing activities, broadcasts, and other operations on it as the activity manager requests."
Muitos detalhes foram ocultados para simplificar o entendimento. Para uma visão completa desta classe, você pode consultar aqui.
Não entraremos em detalhes sobre o Looper
nem Handler
aqui, pois estes serão abordados nos próximos posts. Vamos manter o foco apenas em threads.
ActivityThread#main()
Vamos comentar rapidamente sobre o que está acontecendo dentro do método main dessa classe.
- Já vimos que a thread principal é criada ao iniciar a execução do método main pela JVM. Aqui no Android não é diferente, então ao iniciar a execução desse método, já estamos na main thread.
- O Android vincula um
Looper
e associa umHandler
a main thread para permitir que mensagens sejam trocadas e processadas pela main thread. - Em
Looper.loop()
internamente temos umfor(;;)
o que não deixa que a thread main finalize a sua execução até que oquit
seja chamado:
Para esse post era isso! Não entraremos em mais detalhes sobre a main thread nesse momento, já que esse será o tema de um próximo post! 😅
Parte 2 — Handler, Looper e MessageQueue
Obrigado por ler até aqui! Se você aprendeu algo novo e gostou desse post, não deixe de compartilhá-lo com outros devs que você conhece 😁👍🏻.