Android:Activity.runOnUiThread和View.post有什么区别?


97

Activity.runOnUiThread和之间有什么区别View.post,请问有人可以解释吗?


Answers:


104

没有真正的区别,除了View.post在您无法直接访问活动时会有所帮助。

在这两种情况下,如果不在UI线程上,Handler#post(Runnable)都将在后台调用。

如评论中提到的CommonsWare所述,两者之间是有区别的-在Ui线程上Activity#runOnUiThread调用时,将run直接调用该方法,而View#post将其发布runnable到队列中(例如调用Handler#post

IMO的重点是两者都有相同的目标,对于使用该目标的人来说,应该没有区别(并且将来的实现可能会发生变化)。


70
区别之一:runOnUiThread()检查当前线程,Runnable如果碰巧在主应用程序线程上,则立即执行。无论调用什么线程,post()总是将其Runnable放在队列中。
CommonsWare,2012年

谢谢,我现在可以根据您的解释和@CommonsWare注释看到区别。
亚历山大·库利亚克汀

4
@Ashwin:“您说过runOnUiThread()立即执行Runnable” –不,我没有。请重新阅读评论。我说过“ 如果我们碰巧在主应用程序线程上,请runOnUiThread()检查当前线程并Runnable立即执行”(强调)。“这是否意味着将忽略UI线程上的当前内容,并且将其放在首位?” - “什么都目前在UI线程” 的电话。runOnUiThread()
CommonsWare,2012年

1
@ barn.gumbl:在这种情况下,我查看了源代码。
CommonsWare 2014年

1
这里一个区别。发布到未附加到窗口的视图将不会执行任何操作。虽然不是一个很大的区别,这可能会导致微妙的错误,是相当恼人的导航,如果你不知道存在差异。
dcow

23

Activity.runOnUiThread和view.post()之间的另一个区别是,在将视图附加到窗口之后调用view.post()中的runnable。


你是什​​么意思显示?变得可见?根本不要求看不见的视图吗?
2014年

纠正了亚历克斯的歧义。
pareshgoel 2014年

5
这是恕我直言的最重要的区别。很多人使用view.post()来执行需要在附加视图之后执行的内容。
索提2015年

3
这不是真的。这从来都不是真的,但是在某些时候,View.java的JavaDoc确实错误地指出“当将View连接到窗口时,View.post仅可从另一个线程运行”。该问题已于2012年10月15日修复,但花了一些时间才能渗透到Android开发人员的脑海中。
亚历克斯·科恩

@pareshgoel源于此差异?
apostleofzion,2016年

17

对于大多数情况而言,这两种方法都是可以接受的,并且在大多数情况下它们是可以互换的,但是它们之间存在细微的差异。当然,最大的区别是一个可以从那里获得Activity,另一个可以从那里获得View。两者之间有很多重叠之处,但有时在中Activity您将无法访问View,而有时在中View您将无法访问Activity

我遇到的一些极端情况是在另一个SO问题的答案中View.post提到View.postView.post仅当将附加到窗口时,才能从另一个线程工作View。这很少有问题,但有时可能导致Runnable永不执行,特别是如果您View.post使用的onCreate方法调用Activity。另一种方法是使用Handler.post这就是Activity.runOnUiThreadView.post使用被窝里呢。

(出于准确性进行了编辑,“从另一个线程添加”)


1
拆装时onCreate()也会失败吗?嗯,在这种情况下,我希望它可以发布到Handler提供的内容ViewRoot
詹斯(Jens)2012年

5
@Jens是的,我浏览了源代码,View.post应该将其添加Runnable到队列中,如果尚未连接,则稍后再执行。我没有在源代码中进行更深入的研究,但是文档确实说:“仅当此View附加到窗口时,才可以从UI线程外部调用此方法。” 所以我认为,如果它在当前线程上,则您所说的是正确的;如果不是,则可能只是吞下了Runnable。我当然在我的代码中发生过这种情况。
kabuko

@kabuko谢谢您的回答从另一个角度显示了它。我怎么接受不了一个以上的答案?看不到背后的逻辑将导致出现在元论坛上
Alexander Kulyakhtin 2012年

3
这不是真的。这从来都不是真的,但是在某些时候,View.java的JavaDoc确实错误地指出“当将View连接到窗口时,View.post仅可从另一个线程运行”。该问题已于2012年10月15日修复,但花了一些时间才能渗透到Android开发人员的脑海中。
亚历克斯·科恩

0

另一个区别post是:每个View;runOnUiThread是根据活动。

这意味着(将来吗?)无需您自己的跟踪或过滤代码就可以执行view.getQueue/ activity.getQueue并完全获得所需的内容。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.