Handler vs AsyncTask

128

Estou confuso sobre quando alguém escolheria o AsyncTask em vez de um manipulador. Digamos que tenho algum código que desejo executar a cada n segundos que atualizará a interface do usuário. Por que eu escolheria um sobre o outro?

Steve
fonte
1
Isso ficou mais complicado com o AsyncTaskLoaders. Consulte stackoverflow.com/q/7120813/969325 para obter mais informações.
Warpzit

Respostas:

75

IMO, o AsyncTask foi criado para fornecer uma maneira conveniente e fácil de usar para obter o processamento em segundo plano em aplicativos Android, sem se preocupar muito com os detalhes de baixo nível (threads, loops de mensagens etc.). Ele fornece métodos de retorno de chamada que ajudam a agendar tarefas e também a atualizar facilmente a interface do usuário sempre que necessário.

No entanto, é importante observar que, ao usar o AsyncTask, um desenvolvedor está submetendo suas limitações, o que resultou devido às decisões de design que o autor da classe tomou. Por exemplo, descobri recentemente que há um limite para o número de trabalhos que podem ser agendados usando AsyncTasks.

O manipulador é mais transparente dos dois e provavelmente oferece mais liberdade; portanto, se você quiser ter mais controle sobre as coisas, escolha Handler, caso contrário, o AsynTask funcionará bem.

Samuh
fonte
Está certo. Eu estava usando AsyncTasks para todas as operações em segundo plano no meu projeto. Em algum momento, comecei a atingir o limite máximo de tarefas, para que minhas tarefas fossem iniciadas somente após a conclusão de outra. No final, tive que mudar toda a minha estrutura para parar de usar asynctasks e evitar atingir essa limitação.
tbraun
5
A partir do Honeycomb, AsyncTaskssão executados em um thread, portanto, não há mais paralelismo. Você ainda pode executá-los em uma Executorimplementação paralela .
MrSnowflake
63

Minha regra geral seria:

  • Se você estiver fazendo algo isolado relacionado à interface do usuário, por exemplo, baixar dados para apresentar em uma lista, vá em frente e use AsyncTask.

  • Se você estiver executando várias tarefas repetidas, por exemplo, o download de várias imagens que serão exibidas ImageViews(como o download de miniaturas) durante o download, use uma fila de tarefas com Handler.

alexanderblom
fonte
O manipulador está no nível 1 da API e o ASYNCTASK no nível 3 da API. Será preterido a qualquer custo? becaz estou concentrando-se em portar aplicações de versões anteriores para 2.2 e 2.3 ..
yokks
10
Nenhum deles será descontinuado em breve. O manipulador nunca será preterido, pois a interface do usuário é basicamente criada em torno dele.
Alexanderblom
Você não deve usar um carregador para carregar dados para a sua interface do usuário apresentar?
Nbarraille 27/05
19

Sempre tente evitar o uso do AsyncTask quando possível, principalmente pelos seguintes motivos:

  • Não é garantido que o AsyncTask seja executado, pois há uma base ThreadPool e um tamanho máximo definidos pelo sistema e, se você criar um assíncrono em excesso, eles serão destruídos.

  • O AsyncTask pode ser encerrado automaticamente, mesmo durante a execução, dependendo do ciclo de vida da atividade e você não tem controle sobre ele

  • Os métodos AsyncTask em execução no thread da interface do usuário, como onPostExecute, podem ser executados quando a atividade a que se refere, não está mais visível ou está possivelmente em um estado de layout diferente, como após uma mudança de orientação.

Concluindo, você não deve usar os métodos vinculados ao UIThread do AsyncTask, que é sua principal vantagem !!! Além disso, você só deve realizar trabalhos não críticos no doInBackground. Leia este tópico para obter mais informações sobre esses problemas:

O AsyncTask é realmente conceitualmente defeituoso ou estou perdendo alguma coisa?

Para concluir, tente preferir usar IntentServices, HandlerThread ou ThreadPoolExecutor em vez de AsyncTask quando qualquer um dos problemas citados acima puder ser uma preocupação para você. Certamente, será necessário mais trabalho, mas seu aplicativo será mais seguro.

type-a1pha
fonte
Sim, passei muito tempo lamentando muitos usos do AsyncTasks. Eles parecem ótimos, mas ... tantos problemas!
SMBiggs
6
Lamento postar com tanta veemência seus pontos de vista, mas não posso deixar seu estilo pobre afetar noobies para o Android. Ponto um. Você NÃO deve ter tantos threads em execução. Se você se deparar com isso, sua arquitetura é foobar. Ponto 2. Como na terra .. Ok, sim, tudo no Android é um jogo gratuito para o coletor de lixo ... Você só veria o comportamento de abserd como descrito acima, em alguns casos estritamente abusivos de tarefas. Ponto 3. Gerenciar sua tarefa, para não ser rude, é uma habilidade iniciante. Você o mata quando liga para a Pausa ou desconecta e anexa adequadamente.
precisa
1
vogella.com/tutorials/AndroidBackgroundProcessing/article.html Isto é tudo que você precisa para aprender a fazer corretamente tarefas sem as questões acima (assumindo que você não está fazendo algo como vomitando algumas centenas de tarefas)
StarWind0
16

Se você deseja fazer um cálculo a cada x segundos, provavelmente deve agendar um Runnableem um Handler(com postDelayed()) e isso Runnabledeve começar no segmento atual da interface do usuário. Se você deseja iniciá-lo em outro segmento, use HandlerThread. O AsyncTask é mais fácil de usar, mas não é melhor que o manipulador.

MrSnowflake
fonte
7

O manipulador está associado ao encadeamento principal do aplicativo. ele lida e agenda mensagens e executáveis ​​enviados de threads em segundo plano para o thread principal do aplicativo.

O AsyncTask fornece um método simples para lidar com threads em segundo plano, a fim de atualizar a interface do usuário sem bloqueá-la por operações demoradas.

A resposta é que ambos podem ser usados ​​para atualizar a interface do usuário a partir de threads em segundo plano, a diferença estaria no seu cenário de execução. Você pode considerar usar o manipulador para enviar mensagens atrasadas ou enviar mensagens para o MessageQueue em uma ordem específica.

Você pode usar o AsyncTask se desejar trocar parâmetros (atualizando a interface do usuário) entre o thread principal do aplicativo e o thread de segundo plano de uma maneira fácil e conveniente.

secretlm
fonte
3
Você pode criar seu próprio manipulador associado a outro segmento.
Aleksejs Mjaliks
O manipulador não está necessariamente vinculado ao thread principal (UI Thread). Ele está vinculado ao encadeamento no qual foi instanciado e manipula as Mensagens ou Runnable que chegam a essa fila de mensagens de encadeamento. Também pode enviar objetos Message e Runnable para esta fila de mensagens de encadeamento.
Azec-pdx
2

AsyncTaskpresume que você fará algo no thread da interface do usuário, após a conclusão de algum trabalho em segundo plano. Além disso, você pode executá-lo apenas uma vez (depois disso, seu status é FINISHEDe você receberá uma exceção ao tentar executá-lo mais uma vez). Além disso, a flexibilidade de usá-lo não é muito. Sim, você pode usar THREAD_POOL_EXECUTORpara uma execução paralela, mas o esforço pode não ser digno.

Handlernão presume nada, exceto manipular Runnables e Mensagens. Além disso, ele pode ser executado quantas vezes você desejar . Você é livre para decidir a qual thread ele deve ser anexado, como ele se comunica com outros manipuladores, talvez produzi-los HandlerThread. Portanto, é muito mais flexível e adequado para trabalhos repetidos.

Confira diferentes tipos de Handlerexemplos aqui .

lomza
fonte
0

Eles são a melhor pergunta de entrevista que é feita. AsyncTask - Eles são usados ​​para descarregar o thread da interface do usuário e executar tarefas em segundo plano. Manipuladores - o dosent Android possui um meio direto de comunicação entre a interface do usuário e o thread de segundo plano. Os manipuladores devem ser usados ​​para enviar mensagens ou executáveis ​​pela fila de mensagens.

Portanto, AsyncTasks são usadas onde as tarefas são necessárias para serem executadas em segundo plano e os Manipuladores são usados ​​para comunicação entre uma interface do usuário e o Thread de segundo plano.

saubhagya das
fonte
0

doInBackground - basicamente funciona em outro segmento. onPostExecute - lança os resultados no thread da interface do usuário e está enviando internamente uma mensagem para o manipulador do thread principal. O thread principal da interface do usuário já possui um looper e um manipulador associados.

Então, basicamente, se você precisar executar alguma tarefa em segundo plano, use o AsyncTask. Mas, em última análise, se algo precisar ser atualizado na interface do usuário, ele estará usando o manipulador do thread principal.

Shinoo Goyal
fonte