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.