Compreender o Núcleo Android: Looper, Handler, and HandlerThread

entendendo Android Core: Looper, Handler, and HandlerThread

este artigo abrange Android Looper, Handler, and HandlerThread. Estes estão entre os blocos de construção do sistema operacional Android.

na minha própria experiência, usei – os num contexto muito limitado até recentemente. Meu caso de uso envolveu o envio de tarefas para o tópico principal/ui, principalmente para atualizar a UI de qualquer outro tópico. Os outros aspectos da operação multi-threaded foram tratados através de formas alternativas, como ThreadPoolExecutor, IntentService, e Asyntsck.

MultiThreading and task running are old subjects. Java em si tem java.util.pacote concomitante e estrutura de bifurcação / junção para facilitar. Várias bibliotecas foram escritas para agilizar operações assíncronas. RxJava é a biblioteca mais popular de hoje para Programação Reativa e projetar uma aplicação assíncrona.Então, por que estou escrevendo sobre a velha escola?

Looper, Handler, e HandlerThread são a maneira do Android de resolver os problemas da programação assíncrona. Eles não são da velha escola, mas uma estrutura arrumada em que um complexo Android framework é construído.

para os novos desenvolvedores, é altamente recomendável entender os princípios por trás deles e experimentar um deve revisitar este tópico para recordar os detalhes menores.

também criei um tutorial de vídeo para este assunto, e recomendo vivamente que o assista. Clique aqui para ver agora.Casos De Utilização:

  1. o fio principal do Android é construído com um Looper e Handlers. Assim, a compreensão dele é essencial para criar uma UI responsiva desbloqueada.
  2. os desenvolvedores que escrevem bibliotecas não podem se dar ao luxo de usar bibliotecas de terceiros por causa do tamanho da biblioteca. Então, para eles, a melhor opção é utilizar o recurso disponível existente. Escrever a própria solução para ele pode nem sempre obter esse nível de eficiência e otimização.
  3. o mesmo argumento também pode ser feito para empresas / indivíduos que enviam SDKs. Os clientes podem ter implementações variadas,mas todos eles vão compartilhar a APIs de framework android comum.A sua compreensão total irá aumentar a capacidade de seguir as classes Android SDK e package em geral.

vamos começar a exploração / revisão com um questionário.

espero que o leitor tenha a compreensão básica de Java threads. Se você precisar, então obtenha uma visão geral rápida do Java Thread e Runnable.

Qual é o problema com a linha java?

java threads são usados apenas uma vez e morrem depois de executar seu método de execução.Podemos melhorá-lo?

o fio é uma espada de dois gumes. Podemos acelerar a execução, distribuindo as tarefas entre os fios da execução, mas também podemos atrasá-la quando os fios estão em excesso. A criação de fio em si é uma sobrecarga. Assim, a melhor opção é ter um número ótimo de threads e reutilizá-los para a execução de Tarefas.

modelo para a reusabilidade do fio:

  1. o fio é mantido vivo, em um loop através do método run().
  2. a tarefa é executada serialmente por essa thread e é mantida em uma fila (Messageque).
  3. o fio deve ser terminado quando terminado.

Qual é a maneira do andróide fazer isso?

o modelo acima é implementado no Android via Looper, Handler, e HandlerThread. O sistema pode ser visualizado para ser um veículo como na capa do artigo.

  1. MessageQueue é uma fila que tem tarefas chamadas mensagens que devem ser processadas.
  2. Handler colocar a tarefa em fila de espera na MessageQueue usando Looper e também executá-la quando a tarefa sair da MessageQueue.
  3. Looper é um trabalhador que mantém um fio vivo, loops através de MessageQueue e envia mensagens para o correspondente handler para processar.
  4. Finally Thread gets terminated by calling Looper’s quit() method.

um fio pode ter apenas um laço único e pode ter muitos manipuladores únicos associados a ele.

criando Looper e Messageque para um fio:

um fio recebe um Looper e MessageQueue chamando Looper.prepare() após a sua execução. Looper.prepare() identifica o fio chamador, cria um objeto Looper e MessageQueue e associa o thread com eles na classe de armazenamento ThreadLocal. Looper.loop() deve ser chamado para iniciar o laço associado. Da mesma forma, o looper deve ser encerrado explicitamente através de looper.quit().

class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here // this will run in non-ui/background thread } }; Looper.loop(); } }

criando manipulador para um fio:

a Handler fica implicitamente associado com o fio que o instancia através de fio Looper , mas podemos explicitamente amarrá-lo a um fio passando o fio looper no construtor do Handler.

handler = new Handler() {@Overridepublic void handleMessage(Message msg) { // process incoming messages here // this will run in the thread, which instantiates it }};

Envio de mensagens para o MessageQueue por Handler pode ser feito de dois modos:

  1. Message: é uma classe que define vários métodos úteis para lidar com dados de mensagem. Para enviar um objeto, definimos a variável obj.

Message msg = new Message();msg.obj = "Ali send message";handler.sendMessage(msg);

visão geral detalhada da classe Message pode ser encontrada aqui: https://developer.android.com/reference/android/os/Message.html

Runnable: um runnable também pode ser publicado na MessageQueue. Ex: postar e executar uma tarefa no tópico principal.

new Handler(Looper.getMainLooper()).post(new Runnable() {@Overridepublic void run() { // this will run in the main thread }});

no exemplo acima, criamos um Handler e fornecemos Looper associado com o fio principal. Isto associa este manipulador ao fio principal. Quando postamos o Runnable, ele fica em fila de espera na linha principal MessageQueue e então executado na linha principal.

Handler é capaz de manipulação de mensagens de uma grande variedade de maneiras, que podem ser encontradas aqui: https://developer.android.com/reference/android/os/Handler.html

criar uma linha própria e fornecer Lopper e MessageQueue não é a maneira certa de lidar com o problema. Assim, o Android forneceu HandlerThread(subclasse de Thread) para agilizar o processo. Internamente, faz as mesmas coisas que nós fizemos, mas de uma forma robusta. Então, use sempre HandlerThread.

uma das maneiras de criar o HandlerThread é subclassá-lo e na maioria das vezes você estará usando este método.

private class MyHandlerThread extends HandlerThread { Handler handler; public MyHandlerThread(String name) { super(name); } @Override protected void onLooperPrepared() { handler = new Handler(getLooper()) { @Override public void handleMessage(Message msg) { // process incoming messages here // this will run in non-ui/background thread } }; }}

Nota: temos instanciado o manipulador quando o onLooperPrepared() é chamado. Então, esse Handler pode ser associado com esse Looper.

  1. Looper é apenas preparado após o HandlerThread start() é chamado, ou seja, depois que o fio está rodando.
  2. a Handler pode ser associado a HandlerThread, apenas depois de estar preparado Looper.

outra forma de criar o pão:

HandlerThread handlerThread = new HandlerThread("MyHandlerThread");handlerThread.start();Handler handler = new Handler(handlerThread.getLooper());

Nota: HandlerThread precisa chamar myHandlerThread.quit() para libertar os recursos e parar a execução do fio.Eu sugeria praticar os códigos acima, para que você possa entender seus pequenos detalhes.

eu criei um projeto de exemplo para simulação de correios. Os Correios são construídos sobre HandlerThread e os clientes comunicam com a ajuda dos Correios. Uma classe de simulador cria poucos robôs clientes e delega sua comunicação para a Mainactividade, o que a torna em um feed ao vivo.

o link para este exemplo

eu também criei um tutorial de vídeo para este assunto,e eu recomendo muito assistir. Clique aqui para ver agora.

também, vamos nos tornar amigos no Twitter, Linkedin, Github e Facebook.Aprender é uma viagem, vamos aprender juntos!

Deixe uma resposta

O seu endereço de email não será publicado.