Android: в чем разница между Activity.runOnUiThread и View.post?

97

В чем разница между Activity.runOnUiThreadи View.post, может кто-нибудь объяснить?

Александр Куляхтин
источник

Ответы:

104

Нет никакой реальной разницы, кроме View.post это полезно, когда у вас нет прямого доступа к активности.

В обоих случаях, если не в потоке пользовательского интерфейса, Handler#post(Runnable) будет вызываться за кулисами.

Как упоминалось в комментарии CommonsWare, между ними есть разница - при вызове в потоке пользовательского интерфейса Activity#runOnUiThreadвызовет runметод напрямую, в то время как View#postотправит его runnableв очередь (например, вызовет Handler#post)

Важным моментом IMO является то, что оба имеют одну и ту же цель, и для тех, кто ее использует, не должно быть никакой разницы (и реализация может измениться в будущем).

МБыД
источник
70
Одно отличие: runOnUiThread()проверяет текущий поток и Runnableнемедленно выполняет, если мы оказались в основном потоке приложения. post()всегда помещает в Runnableочередь, независимо от того, в каком потоке он вызван.
CommonsWare
Спасибо, теперь я вижу разницу на основе вашего объяснения и комментария @CommonsWare.
Александр Куляхтин
4
@Ashwin: «Вы сказали, что runOnUiThread () немедленно выполняет Runnable» - нет, я этого не делал. Пожалуйста, перечитайте комментарий. Я сказал: « runOnUiThread()проверяет текущий поток и Runnableнемедленно выполняет его, если мы оказались в основном потоке приложения » (выделено мной). «Означает ли это, что все, что в данный момент находится в потоке пользовательского интерфейса, игнорируется, и этому предоставляется первый приоритет?» - «все, что в данный момент находится в потоке пользовательского интерфейса» - это runOnUiThread()вызов.
CommonsWare
1
@ barn.gumbl: В этом случае я посмотрел на источник.
CommonsWare
1
Там является разница. Публикация в представлении, которое не прикреплено к окну, ничего не даст. Хотя и не огромная разница, это может привести к тонким ошибкам и очень раздражает ориентироваться , если вы не знают , разница существует.
dcow
23

Еще одно различие между Activity.runOnUiThread и view.post () заключается в том, что runnable в view.post () вызывается после того, как представление прикреплено к окну.

парешгоэль
источник
Как вы имеете в виду показали? Становится видимым? Вы вообще не обращались к невидимому виду?
Александр Куляхтин
Исправил двусмысленность Алекс.
парешгоэль
5
ИМХО это самая главная разница. Многие люди используют view.post () для выполнения вещей, которые необходимо выполнить ПОСЛЕ прикрепления представления.
Сотти,
3
Это неправда. Это никогда не было правдой, но в какой-то момент JavaDoc для View.java ошибочно утверждал, что «View.post работает только из другого потока, когда View прикреплен к окну». Это было исправлено 15 октября 2012 года, но потребовалось время, чтобы проникнуть в сознание разработчиков Android.
Alex Cohn
@pareshgoel источник этой разницы?
apostleofzion
17

Либо являются приемлемыми для большинства ситуаций и по большей части они являются взаимозаменяемыми, но они являются тонко разные. Самая большая разница, конечно, в том, что один доступен из файла, Activityа другой из View. Там очень много перекрытия между тем, но иногда в Activityне будет иметь доступ к View, а иногда и в Viewвас не будет иметь доступ кActivity .

Один из крайних случаев, с которыми я столкнулся, View.postя упомянул в ответе на другой вопрос SOView.post : View.postработает только из другого потока, когда Viewон прикреплен к окну. Это редко проблема, но иногда может привести к тому, Runnableчтобы никогда не выполнить, особенно , если вы звоните View.postв onCreateметоде из ваших Activity. Альтернатива - использовать то, Handler.postчто есть, Activity.runOnUiThreadи View.postв любом случае использовать под одеялом.

(отредактировано для точности, добавлено «из другой ветки»)

Кабуко
источник
1
Он также может выйти из строя, когда он отключен onCreate()? Хм, я бы ожидал, что в этом случае он будет отправлен на адрес Handlerпоставщика ViewRoot.
Йенс
5
@Jens Да, я взглянул на источник и View.postдолжен добавить Runnableего в очередь для выполнения позже, если он еще не прикреплен. Я не копался глубже в исходном коде, но в документации действительно говорится: «Этот метод может быть вызван извне потока пользовательского интерфейса, только когда это представление прикреплено к окну». Поэтому я думаю, что если он находится в текущем потоке, то то, что вы сказали, верно, если это не так, то, вероятно, он просто проглатывает Runnable. В моем коде это наверняка случалось.
kabuko
@kabuko Спасибо, ваш ответ показывает это с другой точки зрения. Как это, я не могу принять более одного ответа, не вижу логики в том, что он будет
адресован метафоруму
3
Это неправда. Это никогда не было правдой, но в какой-то момент JavaDoc для View.java ошибочно утверждал, что «View.post работает только из другого потока, когда View прикреплен к окну». Это было исправлено 15 октября 2012 года, но потребовалось время, чтобы проникнуть в сознание разработчиков Android.
Alex Cohn
0

Еще одно отличие: postза просмотр; runOnUiThreadза действие.

Это означает, что можно будет (в будущем?) Делать view.getQueue/ activity.getQueueполучать именно то, что вы хотите, без вашего собственного кода отслеживания или фильтрации.

Pacerier
источник