真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

使用View.post()需要注意什么

這篇文章給大家分享的是有關(guān)使用View.post()需要注意什么的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

創(chuàng)新互聯(lián)公司是專業(yè)的松原網(wǎng)站建設(shè)公司,松原接單;提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行松原網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!

一、前言

有時(shí)候,我們會(huì)需要用到 View.post() 方法,來(lái)將一個(gè) Runnable 發(fā)送到主線程去執(zhí)行。這一切,看似很美好,它最終會(huì)通過(guò)一個(gè) Handler.post() 方法去執(zhí)行,又避免我們重新定義一個(gè) Handler 對(duì)象。

但是,從 Android 7.0(Api level 24) 開(kāi)始,View.post() 將不再那么靠譜了,你 post() 出去的 Runnable ,可能永遠(yuǎn)也不會(huì)有機(jī)會(huì)執(zhí)行到。

二、post 在 7.0 的差異

2.1 post 方法的差異

前面提到,這個(gè)問(wèn)題只出現(xiàn)在 Android 7.0 上。那么就先從源碼分析 Android 7.0 到底對(duì) View.post() 做了什么改動(dòng)。

使用View.post()需要注意什么

用 Diff 看一下它們的差異,左邊是 Api Level 24+(以下簡(jiǎn)稱 Api24) 的代碼,右邊是 Api level 23-(以下簡(jiǎn)稱 Api23) 的代碼。

很明顯的可以看出來(lái),它們只有在 mAttachInfo 為 null 的時(shí)候,執(zhí)行的邏輯才會(huì)有差異。

Api24 中,會(huì)調(diào)用 getRunQueue().post(action),而 Api23 會(huì)調(diào)用 ViewRootImpl.getRunQueue().post(action) 方法,他們的差異就在這里。

2.2 Api23 post 的細(xì)節(jié)

先簡(jiǎn)單理解一下,ViewRootImpl 是什么。

ViewRootImpl 可以理解是一個(gè) Activity 的 ViewTree 的根節(jié)點(diǎn)的實(shí)例。每個(gè) ViewRootImpl 就是用來(lái)管理 DecorView 和 ViewTree。

ViewRootImpl 中的用來(lái)承載 Runnable 的隊(duì)列是 sRunQueues ,它一個(gè)靜態(tài)的變量,也就是說(shuō)在 App 的生命周期內(nèi),ViewRootImpl 中的這個(gè)消息隊(duì)列都是同一個(gè)。

再來(lái)看看前面提到的 ViewRootImpl.getRunQueue().post() 到底干了什么?

使用View.post()需要注意什么

post() 方法只是單純的將它包裝成一個(gè) HandlerAction 對(duì)象,然后放入 mActions 這個(gè) ArrayList 中。繼續(xù)追查下去就需要知道 mActions 中添加的 HandlerAction 在何時(shí)被消費(fèi)掉了。

消費(fèi) HandlerAction 的地方,是 executeActions() 方法。

使用View.post()需要注意什么它最終,還是調(diào)用的 handler.postDelayed() ,這沒(méi)什么好說(shuō)的,關(guān)鍵點(diǎn)在于 executeAction() 方法,是在什么時(shí)候被調(diào)用的。

executeAction() 是被 TraversalRunnable 調(diào)用 doTraversa() ,在doTraversa() 方法中,進(jìn)行調(diào)用的。而 TraversalRunnable 又是通過(guò) Choreographer.postCallBack() 去循環(huán)調(diào)用的。這個(gè) Choreographer 通過(guò) doScheduleCallback() 發(fā)送一個(gè) MSG_DO_SCHEDULE_CALLBACK 類型的消息循環(huán)調(diào)用,間隔就是一個(gè) VSync 的間隔。

關(guān)于 Choreographer ,不是本文的重點(diǎn),有興趣可以單獨(dú)了解一下。

所以,在 Api23 以下,executeAction() 是會(huì)被循環(huán)調(diào)用,基本上其內(nèi)的 mActions 只要有未執(zhí)行的 Runnable 立刻就會(huì)被消費(fèi)掉。

所以在 Api23 以下的設(shè)備上,View.post() 基本上是靠譜的,post 出去的 Runnable 都會(huì)有機(jī)會(huì)執(zhí)行到。

2.3 Api24 的細(xì)節(jié)

再來(lái)看看在 Api24 中的實(shí)現(xiàn)細(xì)節(jié),在 Api24 中,調(diào)用的是 getRunQueue().post() 方法,它操作的是一個(gè) HandlerActionQueue 對(duì)象。

使用View.post()需要注意什么

內(nèi)部的結(jié)構(gòu)其實(shí)和 Api23 很像,也是維護(hù)了一個(gè) HandlerAction 的數(shù)組 mActions 。

最終消費(fèi)掉 mActions 的地方,依然是一個(gè) executeActions() 方法。

使用View.post()需要注意什么

回到根本的問(wèn)題,executeActions() 方法在什么時(shí)機(jī)會(huì)被調(diào)用到,繼續(xù)追查可以看到它在 View.dispatchAttachedToWindow() 方法中,會(huì)被調(diào)用。

使用View.post()需要注意什么

既然,executeActions() 方法,在 Api24 及以上,只會(huì)在 dispatchAttachedToWindow() 的方法中,才有機(jī)會(huì)被調(diào)用到,而 View.dispatchAttachedToWindow() 方法,只有在這個(gè) View 通過(guò) addView() 等方法,加入到一個(gè) ViewGroup 的時(shí)候,才會(huì)被調(diào)用到。這就導(dǎo)致寫(xiě)在 Layout 布局中的控件,是不會(huì)有機(jī)會(huì)再調(diào)用 addView() 方法的,所以它永遠(yuǎn)也得不到執(zhí)行。這也就到時(shí)了 Api24 下,View.post() 表現(xiàn)的現(xiàn)象不一致的緣故。

感謝各位的閱讀!關(guān)于“使用View.post()需要注意什么”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!


當(dāng)前題目:使用View.post()需要注意什么
文章出自:http://weahome.cn/article/poecgg.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部