Android: qual è la differenza tra Activity.runOnUiThread e View.post?


Risposte:


104

Non c'è alcuna differenza reale, tranne che View.postè utile quando non si ha un accesso diretto all'attività.

In entrambi i casi, se non su thread UI, Handler#post(Runnable)verrà chiamato dietro le quinte.

Come menzionato da CommonsWare nel commento, c'è una differenza tra i due: quando viene chiamato sul thread Activity#runOnUiThreaddell'interfaccia utente , chiamerà il runmetodo direttamente, mentre View#postpubblicherà il runnablesulla coda (ad esempio, chiama il Handler#post)

Il punto importante IMO è che entrambi hanno lo stesso obiettivo e, per chiunque lo utilizzi, non dovrebbe esserci alcuna differenza (e l'implementazione potrebbe cambiare in futuro).


70
Una differenza: runOnUiThread()controlla il thread corrente ed esegue Runnableimmediatamente se ci troviamo sul thread dell'applicazione principale. post()mette sempre Runnablein coda, indipendentemente dal thread su cui viene chiamato.
CommonsWare

Grazie, ora posso vedere la differenza in base alla tua spiegazione e al commento di @CommonsWare.
Alexander Kulyakhtin

4
@Ashwin: "Hai detto che runOnUiThread () esegue immediatamente il Runnable" - no, non l'ho fatto. Si prega di rileggere il commento. Ho detto " runOnUiThread()controlla il thread corrente ed esegue Runnableimmediatamente se ci troviamo nel thread principale dell'applicazione " (enfasi aggiunta). "Significa che ciò che è attualmente sul thread dell'interfaccia utente viene ignorato e a questo viene data la priorità?" - "ciò che è attualmente nel thread dell'interfaccia utente" è la runOnUiThread()chiamata.
CommonsWare

1
@ barn.gumbl: In questo caso, ho guardato la fonte.
CommonsWare

1
V'è una differenza. Pubblicare in una vista che non è allegata a una finestra non farà nulla. Anche se non è una differenza enorme , questo può causare bug sottili ed è abbastanza fastidioso da navigare se non si è consapevoli che la differenza esiste.
dcow

23

Un'altra differenza tra Activity.runOnUiThread e view.post () è che il runnable in view.post () viene chiamato dopo che la vista è attaccata a una finestra.


Come intendi mostrato? Diventa visibile? Non hai affatto chiamato una vista invisibile?
Alexander Kulyakhtin

Corretta l'ambiguità Alex.
pareshgoel

5
Questa è la differenza più importante IMHO. Molte persone usano view.post () per eseguire cose che devono essere eseguite DOPO che la vista è stata allegata.
Sotti

3
Questo non è vero. Questo non è mai stato vero, ma a un certo punto JavaDoc per View.java ha dichiarato erroneamente che "View.post funziona solo da un altro thread quando la vista è collegata a una finestra". Questo problema è stato risolto il 15 ottobre 2012, ma ci è voluto del tempo per penetrare nelle menti degli sviluppatori Android.
Alex Cohn

@pareshgoel fonte per questa differenza?
apostleofzion

17

Entrambi sono accettabili per la maggior parte delle situazioni e per la maggior parte sono intercambiabili, ma sono leggermente diversi. La più grande differenza, ovviamente, è che uno è disponibile da un Activitye l'altro da un View. Ci sono molte sovrapposizioni tra questi, ma a volte in un Activitynon avrai accesso a un View, ea volte in un Viewnon avrai accesso a un Activity.

Uno dei casi limite che ho riscontrato l' View.postho menzionato in una risposta a un'altra domanda SOView.post : View.postfunziona solo da un altro thread quando Viewè collegato a una finestra. Questo è raramente un problema, ma a volte può far sì che il file Runnablenon venga mai eseguito, specialmente se chiami View.postnel onCreatemetodo del tuo Activity. Un'alternativa è usare quello Handler.postche è cosa Activity.runOnUiThreade View.postusare comunque sotto le coperte.

(modificato per precisione, aggiunto "da un altro thread")


1
Può fallire anche se scollegato onCreate()? Hm, in quel caso mi aspetto che venga inviato al Handlerfornito da ViewRoot.
Jens

5
@ Jens Sì, ho guardato l'origine e View.postdovrei aggiungere il Runnablea una coda da eseguire in seguito se non è ancora allegato. Non ho approfondito molto il codice sorgente, ma i documenti dicono: "Questo metodo può essere richiamato dall'esterno del thread dell'interfaccia utente solo quando questa vista è collegata a una finestra". Quindi penso che se è nel thread corrente, allora quello che hai detto è vero, se non lo è allora probabilmente inghiotte solo il Runnable. Sicuramente è successo nel mio codice.
kabuko

@kabuko Grazie, la tua risposta lo mostra da un altro punto. Com'è che non posso accettare più di una risposta non riesco a vedere la logica dietro che deve indirizzare il meta forum
Alexander Kulyakhtin

3
Questo non è vero. Questo non è mai stato vero, ma a un certo punto JavaDoc per View.java ha dichiarato erroneamente che "View.post funziona solo da un altro thread quando la vista è collegata a una finestra". Questo problema è stato risolto il 15 ottobre 2012, ma ci è voluto del tempo per penetrare nelle menti degli sviluppatori Android.
Alex Cohn

0

Un'altra differenza: postè per visualizzazione; runOnUiThreadè per attività.

Ciò significa che sarà possibile (in futuro?) Fare view.getQueue/ activity.getQueuee ottenere esattamente ciò che desideri senza il tuo codice di monitoraggio o filtraggio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.