使用View.post()需要注意什么-創(chuàng)新互聯(lián)

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

成都創(chuàng)新互聯(lián)專注于溆浦企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站建設(shè),成都商城網(wǎng)站開發(fā)。溆浦網(wǎng)站建設(shè)公司,為溆浦等地區(qū)提供建站服務(wù)。全流程按需搭建網(wǎng)站,專業(yè)設(shè)計,全程項目跟蹤,成都創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)

一、前言

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

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

二、post 在 7.0 的差異

2.1 post 方法的差異

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

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

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

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

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

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

先簡單理解一下,ViewRootImpl 是什么。

ViewRootImpl 可以理解是一個 Activity 的 ViewTree 的根節(jié)點的實例。每個 ViewRootImpl 就是用來管理 DecorView 和 ViewTree。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

網(wǎng)頁名稱:使用View.post()需要注意什么-創(chuàng)新互聯(lián)
路徑分享:http://muchs.cn/article32/dhsppc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計、電子商務(wù)App開發(fā)、虛擬主機、響應(yīng)式網(wǎng)站、網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

營銷型網(wǎng)站建設(shè)