Android: Jaka jest różnica między Activity.runOnUiThread a View.post?

Odpowiedzi:

104

Nie ma żadnej różnicy, poza tym, że View.postjest pomocny, gdy nie masz bezpośredniego dostępu do działania.

W obu przypadkach, jeśli nie w wątku UI, Handler#post(Runnable)zostanie wywołany za kulisami.

Jak wspomniano CommonsWare w komentarzach, nie ma różnicy między nimi - w przypadku ich wywoływania Ui nici Activity#runOnUiThreadwywoła runsposób bezpośrednio, podczas gdy View#postumieści runnablesię w kolejce (np wywołać Handler#post)

Ważną kwestią IMO jest to, że oba mają ten sam cel, a dla każdego, kto go używa, nie powinno być żadnej różnicy (a implementacja może się zmienić w przyszłości).

MByD
źródło
70
Jedna różnica: runOnUiThread()sprawdza bieżący wątek i Runnablenatychmiast wykonuje, jeśli znajdujemy się w głównym wątku aplikacji. post()zawsze umieszcza Runnablekolejkę w kolejce, bez względu na to, w jakim wątku jest wywoływana.
CommonsWare
Dziękuję, teraz widzę różnicę na podstawie twojego wyjaśnienia i komentarza @CommonsWare.
Alexander Kulyakhtin
4
@Ashwin: „Powiedziałeś, że runOnUiThread () natychmiast wykonuje Runnable” - nie, nie zrobiłem. Przeczytaj ponownie komentarz. Powiedziałem: „ runOnUiThread()sprawdza bieżący wątek i Runnablenatychmiast wykonuje, jeśli znajdujemy się w głównym wątku aplikacji ” (podkreślenie dodane). „Czy to oznacza, że ​​to, co aktualnie znajduje się w wątku interfejsu użytkownika, jest ignorowane i ma to najwyższy priorytet?” - „cokolwiek jest obecnie na wątku UI” jestrunOnUiThread() wezwanie.
CommonsWare
1
@ barn.gumbl: W tym przypadku spojrzałem na źródło.
CommonsWare
1
Jest to różnica. Publikowanie w widoku, który nie jest dołączony do okna, nic nie da. Chociaż nie jest to duża różnica, może to powodować subtelne błędy i jest dość denerwujące w nawigacji, jeśli nie jesteś świadomy różnicy.
dcow
23

Inną różnicą między Activity.runOnUiThread i view.post () jest to, że funkcja runnable in view.post () jest wywoływana po dołączeniu widoku do okna.

pareshgoel
źródło
Jak masz na myśli pokazane? Staje się widoczny? W ogóle nie powołałeś się na niewidzialny widok?
Alexander Kulyakhtin
Poprawiono niejednoznaczność Alex.
pareshgoel
5
To jest najważniejsza różnica IMHO. Wiele osób używa metody view.post () do wykonywania rzeczy, które muszą zostać wykonane PO dołączeniu widoku.
Sotti
3
To nie jest prawda. To nigdy nie było prawdą, ale w pewnym momencie JavaDoc dla View.java błędnie stwierdził, że „View.post działa tylko z innego wątku, gdy widok jest dołączony do okna”. Zostało to naprawione 15 października 2012 r., Ale wniknięcie do umysłów programistów Androida zajęło trochę czasu.
Alex Cohn
@pareshgoel źródło tej różnicy?
apostleofzion
17

Każda z nich jest akceptowalna w większości sytuacji i w większości są wymienne, ale nieco inne. Największą różnicą jest oczywiście to, że jeden jest dostępny z pliku Activitya, a drugi z pliku View. Są one w dużym stopniu nakładane, ale czasami w a Activitynie będziesz mieć dostępu do a View, a czasami w a Viewnie będziesz mieć dostępu do Activity.

Jeden z skrajnych przypadków, z którymi się spotkałem View.post, wspomniałem w odpowiedzi na inne pytanie SO dotycząceView.post : View.postdziała tylko z innego wątku, gdy Viewjest dołączony do okna. Jest to rzadko są problemem, ale może czasami spowodować Runnable, aby nigdy nie wykonać, zwłaszcza jeśli nazwać View.postw onCreatesposób dokonania Activity. Alternatywą jest użycie tego, Handler.postco jest Activity.runOnUiThreadi View.postużywanie i tak pod osłonami.

(poprawiono dokładność, dodano „z innego wątku”)

kabuko
źródło
1
Może również zawieść, gdy nie jest podłączony onCreate()? Hm, spodziewałbym się, że w takim przypadku wyślę go do Handlerdostarczonego przez ViewRoot.
Jens
5
@Jens Tak, spojrzałem na źródło i View.postpowinienem dodać Runnabledo kolejki do wykonania później, jeśli nie jest jeszcze dołączony. Nie kopałem głębiej w źródle, ale dokumentacja mówi: „Ta metoda może być wywołana spoza wątku interfejsu użytkownika tylko wtedy, gdy ten widok jest dołączony do okna”. Więc myślę, że jeśli jest w bieżącym wątku, to to, co powiedziałeś, jest prawdą, jeśli nie, to prawdopodobnie po prostu połyka Runnable. Z pewnością miałem to w moim kodzie.
kabuko
@kabuko Dziękuję, twoja odpowiedź pokazuje to z innego punktu. Jak to jest, nie mogę zaakceptować więcej niż 1 odpowiedzi, nie widzę logiki
stojącej
3
To nie jest prawda. To nigdy nie było prawdą, ale w pewnym momencie JavaDoc dla View.java błędnie stwierdził, że „View.post działa tylko z innego wątku, gdy widok jest dołączony do okna”. Zostało to naprawione 15 października 2012 r., Ale wniknięcie do umysłów programistów Androida zajęło trochę czasu.
Alex Cohn
0

Kolejna różnica: postdotyczy jednego widoku; runOnUiThreadjest na działanie.

Oznacza to, że będzie można (w przyszłości?) Robić view.getQueue/ activity.getQueuei uzyskiwać dokładnie to, czego chcesz, bez własnego kodu śledzenia lub filtrującego.

Pacerier
źródło