2013-12-20 27 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