Android: Qual é a diferença entre Activity.runOnUiThread e View.post?

Respostas:

104

Não há nenhuma diferença real, exceto que o View.posté útil quando você não tem acesso direto à atividade.

Em ambos os casos, se não no thread da IU, Handler#post(Runnable)será chamado nos bastidores.

Como CommonsWare mencionou no comentário, há uma diferença entre os dois - quando chamado no segmento Ui, Activity#runOnUiThreadirá chamar o runmétodo diretamente, enquanto View#postirá postar o runnablena fila (por exemplo, chamar o Handler#post)

O ponto importante da IMO é que ambos tenham o mesmo objetivo, e para quem o utiliza, não deve haver diferença (e a implementação pode mudar no futuro).

MByD
fonte
70
Uma diferença: runOnUiThread()verifica o thread atual e executa Runnableimediatamente se estivermos no thread principal do aplicativo. post()sempre coloca o Runnablena fila, não importa em qual thread seja chamado.
CommonsWare
Obrigado, agora posso ver a diferença com base na sua explicação e no comentário @CommonsWare.
Alexander Kulyakhtin
4
@Ashwin: "Você disse que runOnUiThread () executa o Runnable imediatamente" - não, não disse. Por favor, releia o comentário. Eu disse " runOnUiThread()verifica o thread atual e executa Runnableimediatamente se estivermos no thread principal do aplicativo " (ênfase adicionada). "Isso significa que o que quer que esteja atualmente no thread da interface do usuário será ignorado e terá a primeira prioridade? - "o que quer que esteja atualmente no thread da interface do usuário" é a runOnUiThread()chamada.
CommonsWare
1
@ barn.gumbl: Neste caso, olhei para a fonte.
CommonsWare
1
Não é uma diferença. Postar em uma vista que não está anexada a uma janela não fará nada. Embora não seja uma grande diferença, isso pode causar bugs sutis e é muito chato de navegar se você não estiver ciente da diferença.
dcow
23

Outra diferença entre Activity.runOnUiThread e view.post () é que o executável em view.post () é chamado depois que a visualização é anexada a uma janela.

pareshgoel
fonte
O que você quer dizer com mostrado? Torna-se visível? Não é chamado a uma visão invisível?
Alexander Kulyakhtin
Corrigido a ambigüidade Alex.
pareshgoel
5
Esta é a diferença mais importante IMHO. Muitas pessoas usam view.post () para executar coisas que precisam ser executadas APÓS a visão ser anexada.
Sotti
3
Isso não é verdade. Isso nunca foi verdade, mas em algum ponto o JavaDoc para View.java afirmou erroneamente que "View.post só funciona em outro thread quando a View está anexada a uma janela". Isso foi corrigido em 15 de outubro de 2012, mas demorou um pouco para penetrar nas mentes dos desenvolvedores Android.
Alex Cohn
@pareshgoel fonte para essa diferença?
apostleofzion
17

Ambos são aceitáveis ​​para a maioria das situações e na maioria das vezes são intercambiáveis, mas são sutilmente diferentes. A maior diferença, claro, é que um está disponível em um Activitye o outro em a View. Há muita sobreposição entre eles, mas às vezes em um Activityvocê não terá acesso a um View, e às vezes em um Viewvocê não terá acesso a um Activity.

Um dos casos extremos que encontrei View.postmencionei em uma resposta a outra pergunta sobre o SOView.post : View.postsó funciona a partir de outro thread quando o Viewestá anexado a uma janela. Isso raramente é um problema, mas às vezes pode fazer com que o Runnablenunca seja executado, especialmente se você chamar View.posto onCreatemétodo do seu Activity. Uma alternativa é usar Handler.postwhat is what Activity.runOnUiThreade View.postuse under the covers de qualquer maneira.

(editado para precisão, adicionado "de outro tópico")

kabuko
fonte
1
Ele pode falhar quando desapegado onCreate()também? Hm, espero que seja enviado para o Handlerfornecido por ViewRootnesse caso.
Jens de
5
@Jens Sim, dei uma olhada na fonte e View.postdevo adicionar o Runnablea uma fila para ser executado mais tarde, se ainda não estiver anexado. Não cavei muito mais fundo na fonte, mas a documentação diz: "Este método pode ser invocado de fora do thread de interface do usuário somente quando esta View está anexada a uma janela." Então eu acho que se está no tópico atual, então o que você disse é verdade, se não estiver, provavelmente apenas engole o Runnable. Certamente isso aconteceu em meu código.
kabuko
@kabuko Obrigado sua resposta mostra isso de outro ponto. Como é que eu não posso aceitar mais de 1 resposta, não consigo ver a lógica por trás do endereço do meta fórum
Alexander Kulyakhtin
3
Isso não é verdade. Isso nunca foi verdade, mas em algum ponto o JavaDoc para View.java afirmou erroneamente que "View.post só funciona em outro thread quando a View está anexada a uma janela". Isso foi corrigido em 15 de outubro de 2012, mas demorou um pouco para penetrar nas mentes dos desenvolvedores Android.
Alex Cohn
0

Outra diferença: posté por Visualização; runOnUiThreadé por atividade.

Isso significa que será possível (no futuro?) Fazer view.getQueue/ activity.getQueuee obter exatamente o que você deseja sem seu próprio código de rastreamento ou filtragem.

Pacerier
fonte