Android: Яка різниця між Activity.runOnUiThread та View.post?


97

Яка різниця між Activity.runOnUiThreadіView.post , хтось, будь ласка, може пояснити?


Відповіді:


104

Справжньої різниці немає, за винятком того, що View.post це корисно, коли у вас немає прямого доступу до діяльності.

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

Як згадується в коментарі CommonsWare, між ними є різниця - при Activity#runOnUiThreadвиклику на потік Ui буде викликатиrun метод безпосередньо, тоді як View#postбуде розміщувати runnableв черзі (наприклад, викликати Handler#post)

Важливим моментом ІМО є те, що обидва мають одну і ту ж мету, і для того, хто її використовує, не повинно бути різниці (і впровадження може змінитися в майбутньому).


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 () полягає в тому, що запущений у view.post () виклик відбувається після приєднання подання до вікна.


Як ви маєте на увазі показаний? Стає видимим? Вас взагалі не закликали на невидимий погляд?
Олександр Куляхтин

Виправив двозначність Олексій.
pareshgoel

5
Це найважливіша відмінність ІМХО. Багато людей використовує view.post () для виконання речей, які потрібно виконати ПІСЛЯ додавання подання.
Сотті

3
Це не правда. Це ніколи не було правдою, але в якийсь момент JavaDoc для View.java помилково заявив, що "View.post працює лише з іншого потоку, коли подання прикріплене до вікна". Це було виправлено 15 жовтня 2012 року, але пройшло деякий час, щоб проникнути у свідомість розробників Android.
Alex Cohn,

@pareshgoel джерело для цієї різниці?
apostleofzion

17

Або є прийнятними для більшості ситуацій і здебільшого вони є взаємозамінними, але вони є тонко різні. Найбільша різниця, звичайно, полягає в тому, що один доступний від Activityа, а інший - від View. Між ними є багато перекриттів, але іноді в a Activityви не матимете доступу до a View, а іноді в a Viewви не матимете доступу до an 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 Дякую, ваша відповідь показує це з іншого боку. Як це, я не можу прийняти більше 1 відповіді, я не бачу логіки, за якою
звертатиметься метафорум

3
Це не правда. Це ніколи не було правдою, але в якийсь момент JavaDoc для View.java помилково заявив, що "View.post працює лише з іншого потоку, коли подання прикріплене до вікна". Це було виправлено 15 жовтня 2012 року, але пройшло деякий час, щоб проникнути у свідомість розробників Android.
Alex Cohn,

0

Ще одна відмінність: postє на View;runOnUiThreadприпадає на діяльність.

Це означає, що можна буде (у майбутньому?) Робити view.getQueue/ activity.getQueueі отримувати саме те, що ви хочете, без власного коду відстеження чи фільтрації.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.