2013-12-20 29 views
1

我已经看到了代码示例,其中一个Runnable被发布到我们大概已经在主UI线程上执行的UI线程。例如,here最佳答案建议发布runnable。我知道这意味着runnable将会发布在消息队列的末尾,但我不确定在从UI线程本身发布它的上下文中意味着什么。什么时候建议从UI线程本身发布到UI线程?

似乎任何事情都可以发布为可运行的,所以我们如何知道我们何时必须发布?什么情况下,这是建议或需要实践?

回答

2

底线是通过发布runnable,您等待排队的用户界面更改完成,以便视图更新和闲置。

案例1:您正试图在某些时候访问部分视图,例如:您需要onCreate()中布局的大小,视图已初始化,但未进行测量或绘制。在这种情况下,您希望在绘制并准备好视图时执行代码。通过在UI线程上发布runnable,您将推迟代码的执行,直到绘制并准备好该视图。

案例2: 在Android的许多API调用导致view/layout改变和重绘。例如。调用notifyDataSetChanged()将重绘列表项。 Android不会马上绘制它,而是等待UI线程闲置(像在UI线程上发布可运行的内容)。在这种情况下,如果您致电method A对列表执行一些操作,则返回的值可能不准确,因为尚未绘制或布局更改的视图。在这种情况下,你发布了一个runnable,它在UI队列完成之后执行(基本上意味着已经绘制了改变的视图)

+0

好的答案 - 如果我记得正确的话,我已经遇到了情况1的情况下使用后不一致工作,即有时视图的高度仍然会返回0,我不得不使用ViewTreeObserver,而不是像http: //stackoverflow.com/questions/7733813/how-can-you-tell-when-a-layout-has-been-drawn。 –

1

发布到UI线程的唯一时间是要求是UI元素需要更改并且代码尚未在UI线程上执行(正如您最有可能意识到的那样)。除此之外,仅仅是可能发布到消息队列的其他UI事件的定时问题,或者依赖布局或失效生效的时间。在您链接的示例中,对notifyDataSetChanged()的调用将导致ListView的UI更改在下一个布局之前不会生效,并且通过AdapterView.AdapterDataSetObserver.onChanged()可调用requestLayout()。将命令发布到列表底部可以确保在执行所请求的布局和生成的UI更改之后才执行该命令。

+0

这意味着对我来说,notifyDataSetChanged的一些UI更改是postDelayed()和我们可以通过在主线程上立即执行来导致问题(或者至少不会得到我们预期的顺序)。这是正确的想法吗?为了正确,我们总是应该发布更新UI的任何内容? –

+0

我现在略过了一些源代码,实际上并没有发布任何内容。我会尽快更新我的答案,以便更准确,但总的想法是一样的,因为这是时间问题。如果UI操作的顺序很重要,那么使用发布机制通常是合理的。 – Dave