Eu tenho um pouco confuso sobre as diferenças entre Handlers
, AsyncTask
e Threads
no Android. Eu li vários blogs e perguntas aqui no StackOverflow.
Handler
são threads de segundo plano que fornecem a comunicação com a interface do usuário. A atualização de uma barra de progresso, por exemplo, deve ser feita via Handler
. Usando manipuladores, você tem a vantagem de MessagingQueues
, portanto, se você deseja agendar mensagens ou atualizar vários elementos da interface do usuário ou executar tarefas repetidas.
AsyncTask
são semelhantes, na verdade, eles usam Handler
, mas não são executados no thread da interface do usuário, por isso é bom para buscar dados, por exemplo, buscar serviços da web. Mais tarde, você pode interagir com a interface do usuário.
Thread
no entanto, não pode interagir com a interface do usuário, forneça mais threads "básico" e você perderá todas as abstrações de AsyncTask
.
No entanto, eu gostaria de ter uma conexão de soquete em serviço. Isso deve ser executado em um manipulador ou um encadeamento, ou mesmo umAsyncTask
? A interação da interface do usuário não é necessária. Faz alguma diferença em termos de desempenho que eu uso?
Enquanto isso, a documentação foi amplamente aprimorada.
Handler
não é um encadeamento e não executa nada. É apenas um meio de passar com segurança mensagens de um thread para a fila de mensagens de outro thread . Portanto, normalmente (pelo menos) dois encadeamentos ainda devem ser criados, os quais podem usar um manipulador, mas o manipulador não pode executar nada.Respostas:
Como o tutorial sobre processamento em segundo plano do Android com manipuladores, AsyncTask e Loaders no site da Vogella coloca:
A
Handler
classe pode ser usada para se registrar em um encadeamento e fornece um canal simples para enviar dados para esse encadeamento.A
AsyncTask
classe encapsula a criação de um processo em segundo plano e a sincronização com o thread principal. Ele também suporta o relatório de progresso das tarefas em execução.E a
Thread
é basicamente o elemento principal do multithreading que um desenvolvedor pode usar com a seguinte desvantagem:E em relação ao
AsyncTask
, como a Referência do desenvolvedor do Android coloca:Atualização em maio de 2015: Encontrei uma excelente série de palestras sobre este tópico.
Importante: se você está pensando em usar
AsyncTask
para resolver seus problemas de encadeamento, verifiqueReactiveX/RxAndroid
primeiro um padrão de programação possivelmente mais apropriado. Um recurso muito bom para obter uma visão geral é o Learning RxJava 2 para Android, por exemplo .fonte
Se olharmos para o código fonte, veremos
AsyncTask
eHandler
é puramente escrito em Java. (Existem algumas exceções, no entanto. Mas esse não é um ponto importante)Portanto, não há mágica em
AsyncTask
ouHandler
. Essas classes facilitam nossa vida como desenvolvedor.Por exemplo: Se o Programa A chama o método A (), o método A () pode ser executado em um encadeamento diferente com o Programa A. Podemos verificar facilmente seguindo o código:
Por que devemos usar um novo thread para algumas tarefas? Você pode pesquisar no Google. Muitas razões, por exemplo: levantamento pesado de trabalhos de longa duração.
Então, quais são as diferenças entre
Thread
,AsyncTask
eHandler
?AsyncTask
eHandler
são escritos em Java (internamente, eles usam aThread
), para que tudo o que possamos fazer comHandler
ouAsyncTask
, também possamos usar umThread
.O que pode
Handler
eAsyncTask
realmente ajuda?O motivo mais óbvio é a comunicação entre o segmento de chamada e o segmento de trabalho. ( Thread do chamador : um thread que chama o Thread do trabalhador para executar algumas tarefas. Um thread do chamador não precisa necessariamente ser o thread da interface do usuário). Obviamente, podemos nos comunicar entre dois threads de outras maneiras, mas há muitas desvantagens (e perigos) devido à segurança do thread.
É por isso que devemos usar
Handler
eAsyncTask
. Essas classes fazem a maior parte do trabalho para nós, precisamos apenas saber quais métodos substituir.A diferença entre
Handler
eAsyncTask
é: UseAsyncTask
quando o segmento do chamador for um segmento da interface do usuário . Isto é o que o documento android diz:Quero enfatizar dois pontos:
1) Fácil uso do thread da interface do usuário (portanto, use quando o thread do chamador for UI Thread).
2) Não há necessidade de manipular manipuladores. (significa: você pode usar o manipulador em vez do AsyncTask, mas o AsyncTask é uma opção mais fácil).
Há muitas coisas neste post que ainda não disse, por exemplo: o que é o UI Thread ou por que é mais fácil. Você deve conhecer alguns métodos por trás de cada classe e usá-lo, entenderá completamente o motivo.
@: ao ler o documento do Android, você verá:
Esta descrição pode parecer estranha a princípio. Nós só precisamos entender que cada encadeamento possui cada fila de mensagens (como uma lista de tarefas pendentes), e o encadeamento pegará cada mensagem e fará isso até que a fila de mensagens esteja vazia (assim como terminamos o trabalho e vamos dormir). Então quando
Handler
comunica, apenas envia uma mensagem para o segmento do chamador e aguarda o processamento.Complicado? Lembre-se de que
Handler
pode se comunicar com a linha do chamador com segurança.fonte
Depois de olhar em profundidade, é simples.
AsyncTask
:É uma maneira simples de usar um encadeamento sem saber nada sobre o modelo de encadeamento java .
AsyncTask
fornece vários retornos de chamada respectivos para o segmento de trabalho e o segmento principal.Use para pequenas operações de espera, como as seguintes:
Handler
:Quando instalamos um aplicativo no android, ele cria um thread para esse aplicativo chamado MAIN UI Thread. Todas as atividades são executadas dentro desse segmento. Pela regra do modelo de encadeamento único do Android, não podemos acessar os elementos da interface do usuário (bitmap, textview etc.) diretamente para outro encadeamento definido dentro dessa atividade.
Um manipulador permite que você se comunique de volta com o thread da interface do usuário de outros threads de segundo plano. Isso é útil no Android, pois o Android não permite que outros threads se comuniquem diretamente com o thread da interface do usuário. Um manipulador pode enviar e processar objetos Message e Runnable associados ao MessageQueue de um thread. Cada instância do manipulador está associada a um único encadeamento e à fila de mensagens desse encadeamento. Quando um novo manipulador é criado, ele é vinculado à fila de encadeamentos / mensagens do encadeamento que o está criando.
É o melhor ajuste para:
Thread
:Agora é hora de falar sobre o tópico.
Thread é o pai de ambos
AsyncTask
eHandler
. Os dois usam internamente o encadeamento, o que significa que você também pode criar seu próprio modelo de encadeamento comoAsyncTask
eHandler
, mas isso requer um bom conhecimento da Implementação Multi-Threading do Java .fonte
Um
AsyncTask
é usado para fazer alguma computação em segundo plano e publicar o resultado no encadeamento da interface do usuário (com atualizações de progresso opcionais). Como você não está preocupado com a interface do usuário, umHandler
ouThread
parece mais apropriado.Você pode gerar um plano de fundo
Thread
e passar mensagens de volta ao seu thread principal usando o métodoHandler
'spost
.fonte
Fio
O Android suporta threads Java padrão . Você pode usar Threads padrão e as ferramentas do pacote “
java.util.concurrent
” para colocar ações em segundo plano. A única limitação é que você não pode atualizar diretamente a interface do usuário a partir de um processo em segundo plano.Se você precisar atualizar a interface do usuário a partir de uma tarefa em segundo plano, precisará usar algumas classes específicas do Android. Você pode usar a classe "
android.os.Handler
" para isso ou a classe "AsyncTask
"Handler
A classe "
Handler
" pode atualizar a interface do usuário. Um identificador fornece métodos para receber mensagens e para executáveis. Para usar um manipulador, você deve subclassificá-lo e substituíhandleMessage()
- lo para processar mensagens. Para processarRunable
, você pode usar o métodopost();
Você só precisa de uma instância de um manipulador em sua atividade.Você pode postar mensagens através do método
sendMessage(Message msg)
ousendEmptyMessage
.AsyncTask
Se você tiver um
Activity
que precise baixar conteúdo ou executar operações que podem ser realizadas em segundo plano,AsyncTask
você poderá manter uma interface de usuário responsiva e publicar o progresso dessas operações para o usuário.Para mais informações, você pode dar uma olhada nesses links.
http://mobisys.in/blog/2012/01/android-threads-handlers-and-asynctask-tutorial/
http://www.slideshare.net/HoangNgoBuu/android-thread-handler-and-asynctask
fonte
Thread
:Você pode usar o novo
Thread
para tarefas em segundo plano de longa execução sem afetar o thread da interface do usuário. No java Thread, você não pode atualizar o UI Thread.Como o Thread normal não é muito útil para a arquitetura Android, foram introduzidas classes auxiliares para threading.
Você pode encontrar respostas para suas perguntas na página de documentação de desempenho do Threading .
Manipulador :
A
Handler
permite enviar e processar mensagens eRunnable
objetos associados a um encadeamentoMessageQueue
. CadaHandler
instância está associada a um único encadeamento e à fila de mensagens desse encadeamento.Existem dois usos principais para um
Handler
:Agendar mensagens e executáveis para serem executados como algum ponto no futuro;
Enfileirar uma ação a ser executada em um encadeamento diferente do seu.
AsyncTask :
AsyncTask
permite o uso adequado e fácil do encadeamento da interface do usuário. Essa classe permite que você execute operações em segundo plano e publique resultados no thread da interface do usuário sem precisar manipular threads e / ou manipuladores.Desvantagens:
Por padrão, um aplicativo envia todos os
AsyncTask
objetos criados em um único encadeamento. Portanto, eles são executados de maneira serial e, como no thread principal, um pacote de trabalho especialmente longo pode bloquear a fila. Por esse motivo, use o AsyncTask para manipular itens de trabalho com duração inferior a 5 ms .AsyncTask
Os objetos também são os criminosos mais comuns para problemas de referência implícita.AsyncTask
objetos apresentam riscos relacionados a referências explícitas também.HandlerThread :
Você pode precisar de uma abordagem mais tradicional para executar um bloco de trabalho em um encadeamento de longa execução ( diferente do AsyncTask, que deve ser usado para uma carga de trabalho de 5 ms ), e de alguma capacidade de gerenciar esse fluxo de trabalho manualmente. Um encadeamento de manipulador é efetivamente um encadeamento de longa duração que agarra o trabalho de uma fila e opera nele.
ThreadPoolExecutor :
Essa classe gerencia a criação de um grupo de threads, define suas prioridades e gerencia como o trabalho é distribuído entre esses threads. À medida que a carga de trabalho aumenta ou diminui, a classe gira ou destrói mais threads para ajustar a carga de trabalho.
Se a carga de trabalho for maior e a única
HandlerThread
não for suficiente, você poderáThreadPoolExecutor
Como a interação da interface do usuário não é necessária, você não pode optar por isso
AsyncTask
. Threads normais não são muito úteis e, portanto,HandlerThread
é a melhor opção. Como você precisa manter a conexão do soquete, o Handler no thread principal não é útil. Crie aeHandlerThread
obtenha aHandler
do looper deHandlerThread
.Se você deseja se comunicar novamente com o encadeamento da interface do usuário, poderá usar mais um manipulador para processar a resposta.
no seu
Runnable
, você pode adicionarMais detalhes sobre a implementação podem ser encontrados aqui:
Android: Brinde em um tópico
fonte
Na minha opinião, os threads não são a maneira mais eficiente de fazer conexões de soquete, mas fornecem a maior funcionalidade em termos de threads em execução. Digo que, por experiência, a execução de threads por um longo tempo faz com que os dispositivos fiquem muito quentes e consumam muitos recursos. Mesmo um simples
while(true)
aquecerá um telefone em minutos. Se você diz que a interação da interface do usuário não é importante, talvez umaAsyncTask
seja boa porque elas foram projetadas para processos de longo prazo. Esta é apenas a minha opinião sobre isso.ATUALIZAR
Desconsidere minha resposta acima! Respondi a essa pergunta em 2011, quando eu tinha muito menos experiência no Android do que agora. Minha resposta acima é enganosa e é considerada errada. Estou deixando lá porque muitas pessoas comentaram abaixo, me corrigindo, e eu aprendi minha lição.
Existem outras respostas muito melhores neste tópico, mas pelo menos vou me dar uma resposta mais adequada. Não há nada errado em usar um Java comum
Thread
; no entanto, você deve realmente ter cuidado com a maneira de implementá-lo, pois fazer isso errado pode exigir muito do processador (o sintoma mais notável pode ser o aquecimento do dispositivo).AsyncTask
s são ideais para a maioria das tarefas que você deseja executar em segundo plano (exemplos comuns são E / S de disco, chamadas de rede e chamadas de banco de dados). No entanto,AsyncTask
s não deve ser usado para processos particularmente longos que talvez precisem continuar após o usuário fechar o aplicativo ou colocar o dispositivo em espera. Eu diria que na maioria dos casos, qualquer coisa que não pertença ao thread da interface do usuário pode ser resolvida em umAsyncTask
.fonte
AsyncTask
foi projetado para executar não mais do que alguns segundos de operação a ser executada em segundo plano (não recomendado para megabytes de download de arquivos do servidor ou tarefas intensivas de computação da CPU, como operações de E / S de arquivos). Se você precisar executar uma operação de execução longa, é altamente recomendável usar threads nativos java. Java fornece várias classes relacionadas ao encadeamento para fazer o que você precisa. UseHandler
para atualizar o thread da interface do usuário.fonte
fonte
Deixe-me tentar responder à pergunta aqui com um exemplo :) - MyImageSearch [Consulte a imagem aqui na tela principal de atividades - contendo um texto de edição / botão de pesquisa / exibição em grade]
Descrição do MyImageSearch - Depois que o usuário digitar os detalhes no campo de edição de texto e clicar no botão de pesquisa, pesquisaremos imagens na Internet através dos serviços da web fornecidos pelo flickr (você só precisa se registrar para obter um token de chave / segredo) - para pesquisa, enviamos uma solicitação HTTP e GET JSON Data de volta em resposta, contendo os URLs de imagens individuais que usaremos para carregar a exibição em grade.
Minha implementação - Na atividade principal, definirei uma classe interna que estende o AsyncTask para enviar a solicitação HTTP no método doInBackGround e buscar a resposta JSON e atualizar minha ArrayList local do FlickrItems local que vou usar para atualizar meu GridView via FlickrAdapter (estende o BaseAdapter) e chame o adapter.notifyDataSetChanged () no onPostExecute () do AsyncTask para recarregar a exibição da grade. Observe que aqui a solicitação HTTP é uma chamada de bloqueio por causa da qual eu a fiz através do AsyncTask. Além disso, posso armazenar em cache os itens no adaptador para aumentar o desempenho ou armazená-los no SDCard. A grade que estarei inflando no FlickrAdapter contém na minha implementação uma barra de progresso e uma visualização de imagem. Abaixo você pode encontrar o código para mainActivity que eu usei.
Responda à pergunta agora - Assim que tivermos os dados JSON para buscar imagens individuais, podemos implementar a lógica de obter as imagens em segundo plano por meio de manipuladores, threads ou AsyncTask. Devemos observar aqui que, uma vez que minhas imagens depois de baixadas devem ser exibidas na interface do usuário / thread principal, não podemos simplesmente usar os threads como são, pois eles não têm acesso ao contexto. No FlickrAdapter, as escolhas que eu consegui pensar:
Aqui o código fonte:
Espero que minha resposta, por muito tempo, ajude a entender alguns dos detalhes.
fonte
Depende de qual escolher é baseado no requisito
O Handler é usado principalmente para alternar de outro thread para o thread principal. O Handler é anexado a um looper no qual ele lança sua tarefa executável na fila. Portanto, se você já estiver em outro segmento e alternar para o segmento principal, precisará manipular, em vez de tarefa assíncrona ou outro segmento
Se o manipulador criado em outro segmento que não seja um looper não fornecerá erro quando o identificador for criado, o encadeamento precisará ser transformado em um lopper
O AsyncTask é usado para executar o código por alguns segundos, que é executado no encadeamento em segundo plano e dá seu resultado ao encadeamento principal ** * Limitações do AsyncTask 1. A Tarefa assíncrona não está anexada ao ciclo de vida da atividade e continua sendo executada mesmo que sua atividade seja destruída enquanto o carregador não tem essa limitação 2. Todas as tarefas assíncronas compartilham o mesmo encadeamento em segundo plano para execução, o que também afeta o desempenho do aplicativo
O thread também é usado no aplicativo para trabalhos em segundo plano, mas não tem nenhuma chamada de volta no thread principal. Se o requisito atender a alguns threads em vez de um thread e que precisar executar tarefas várias vezes, o executor do pool de threads será a melhor opção. Exigência de carregamento de imagem de vários URLs como glide.
fonte
Fio
Quando você inicia um aplicativo, um processo é criado para executar o código. Para usar com eficiência os recursos de computação, os encadeamentos podem ser iniciados no processo, para que várias tarefas possam ser executadas ao mesmo tempo. Portanto, os threads permitem criar aplicativos eficientes utilizando a CPU de maneira eficiente, sem tempo ocioso.
No Android, todos os componentes são executados em um único thread principal chamado. Tarefas na fila do sistema Android e execute-as uma a uma no encadeamento principal. Quando tarefas de longa execução são executadas, o aplicativo deixa de responder.
Para evitar isso, você pode criar threads de trabalho e executar tarefas em segundo plano ou longas.
Handler
Como o Android usa o modelo de thread único, os componentes da interface do usuário são criados como não seguros, o que significa que apenas o segmento criado deve acessá-los, o que significa que o componente da interface do usuário deve ser atualizado apenas no segmento principal. Como o componente de interface do usuário é executado no encadeamento principal, as tarefas executadas nos encadeamentos de trabalho não podem modificar os componentes da interface do usuário. É aqui que o Handler entra em cena. O manipulador com a ajuda do Looper pode conectar-se a um novo encadeamento ou a um encadeamento existente e executar o código que ele contém no encadeamento conectado.
O manipulador torna possível a comunicação entre threads. Usando o manipulador, o encadeamento em segundo plano pode enviar resultados para ele e o manipulador conectado ao encadeamento principal pode atualizar os componentes da interface do usuário no encadeamento principal.
AsyncTask
O AsyncTask fornecido pelo Android usa o thread e o manipulador para facilitar a execução de tarefas simples em segundo plano e a atualização dos resultados do thread de segundo plano para o thread principal.
Consulte os segmentos de threads, manipuladores, asynctask e threads do Android para obter exemplos.
fonte
Handler
- é o meio de comunicação entre os threads. No android, é usado principalmente para se comunicar com o thread principal, criando e enviando mensagens através do manipuladorAsyncTask
- é usado para executar aplicativos de execução longa em um encadeamento em segundo plano. Com nAsyncTask
você obtém pode executar a operação em um encadeamento em segundo plano e obter o resultado no encadeamento principal do aplicativo.Thread
- é um processo leve, para obter simultaneidade e utilização máxima da CPU. No Android, você pode usar o thread para realizar atividades que não tocam na interface do aplicativofonte