最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

View.post() 不靠譜的地方你知道多少

 更新時(shí)間:2017年08月29日 15:02:05   作者:承香墨影  
本文給大家分享了view.post()方法不靠譜的地方,以及post在7.0中的差異,需要的的朋友參考下本文吧

一、前言

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

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

二、post 在 7.0 的差異

2.1 post 方法的差異

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

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

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

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

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

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

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

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

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

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

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

它最終,還是調(diào)用的 handler.postDelayed() ,這沒什么好說的,關(guān)鍵點(diǎn)在于 executeAction() 方法,是在什么時(shí)候被調(diào)用的。

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

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

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

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

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

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

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

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

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

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

三、小結(jié)

View.post() 方法,在不同版本的差異,根本原因還是在于 Api23 和 Api24 中,executeActions() 方法的調(diào)用時(shí)機(jī)不同,導(dǎo)致 View 在沒有 mAttachInfo 對象的時(shí)候,表現(xiàn)不一樣了。

所以我們在使用的過程中需要慎用,區(qū)分出實(shí)際使用的場景,一般規(guī)范自己的代碼即可:

在 View 已經(jīng)被顯示出來之后,再調(diào)用 View.post() 方法(這個(gè)時(shí)候 mAttachInfo 已經(jīng)不為空了)。

盡量避免使用 View.post() 方法,可以直接使用 Handler.post() 方法來替代。

總結(jié)

以上所述是小編給大家介紹的View.post() 不靠譜的地方,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • JS實(shí)現(xiàn)圖片高亮展示效果實(shí)例

    JS實(shí)現(xiàn)圖片高亮展示效果實(shí)例

    這篇文章主要介紹了JS實(shí)現(xiàn)圖片高亮展示效果的方法,實(shí)例分析了JavaScript響應(yīng)鼠標(biāo)事件動(dòng)態(tài)操作頁面元素樣式的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • js實(shí)現(xiàn)簡單的計(jì)算器功能

    js實(shí)現(xiàn)簡單的計(jì)算器功能

    本文主要分享了js實(shí)現(xiàn)簡單的計(jì)算器功能的示例代碼。具有一定的參考價(jià)值,下面跟著小編一起來看下吧
    2017-01-01
  • JavaScript實(shí)現(xiàn)點(diǎn)擊按鈕復(fù)制指定區(qū)域文本(推薦)

    JavaScript實(shí)現(xiàn)點(diǎn)擊按鈕復(fù)制指定區(qū)域文本(推薦)

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)點(diǎn)擊按鈕復(fù)制指定區(qū)域文本(推薦)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-11-11
  • js日期相關(guān)函數(shù)dateAdd,dateDiff,dateFormat等介紹

    js日期相關(guān)函數(shù)dateAdd,dateDiff,dateFormat等介紹

    這篇文章主要介紹了js日期相關(guān)函數(shù)dateAdd,dateDiff,dateFormat等介紹,需要的朋友可以參考下
    2016-09-09
  • javascript客戶端遍歷控件與獲取父容器對象示例代碼

    javascript客戶端遍歷控件與獲取父容器對象示例代碼

    本篇文章主要是對javascript客戶端遍歷控件與獲取父容器對象示例代碼進(jìn)行了介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • JS實(shí)現(xiàn)判斷兩個(gè)日期不能跨年和跨月

    JS實(shí)現(xiàn)判斷兩個(gè)日期不能跨年和跨月

    這篇文章主要為大家詳細(xì)介紹了如何利用JavaScript語言實(shí)現(xiàn)判斷兩個(gè)日期不能跨年和跨月,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-04-04
  • 詳解能在多種前端框架下使用的表格控件

    詳解能在多種前端框架下使用的表格控件

    表格控件是我們在開發(fā)中經(jīng)常要用到的控件。有沒有能夠在多種前端控件下都能使用的表格控件?最近研究發(fā)現(xiàn)Wijmo中的FlexGrid是一款不錯(cuò)的表格控件,它能支持很多主流的框架。這里主要介紹在純JavaScript和AngularJS下FlexGrid的使用。
    2017-01-01
  • php對mongodb的擴(kuò)展(初識如故)

    php對mongodb的擴(kuò)展(初識如故)

    mongodb的數(shù)據(jù)存儲格式是一種由于MongoDB的文檔結(jié)構(gòu)為BJSON格式(BJSON全稱:Binary JSON),而BJSON格式本身就支持保存二進(jìn)制格式的數(shù)據(jù),因此可以把文件的二進(jìn)制格式的數(shù)據(jù)直接保存到MongoDB的文檔結(jié)構(gòu)中
    2012-11-11
  • 老生常談的跨域處理

    老生常談的跨域處理

    本文主要介紹了常用的幾種跨域處理方法、跨域的原理解析及實(shí)現(xiàn)方法。具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-01-01
  • text-align:justify實(shí)現(xiàn)文本兩端對齊 兼容IE

    text-align:justify實(shí)現(xiàn)文本兩端對齊 兼容IE

    對于text-align 我們再熟悉不過了,可是它有個(gè)justify屬性,平時(shí)很少用到,就鮮為人知了。justify是一種文本靠兩邊布局方式,一般應(yīng)用于書刊雜志排版;合理運(yùn)用text-align:justify 有時(shí)會省去很多開發(fā)的時(shí)間,通過本文介紹text-align:justify實(shí)現(xiàn)文本兩端對齊 兼容IE
    2015-08-08

最新評論

三原县| 凌源市| 浠水县| 龙山县| 格尔木市| 湘潭县| 西吉县| 香港| 施秉县| 墨玉县| 张家港市| 海门市| 吉木乃县| 股票| 张家口市| 福鼎市| 长治市| 荥经县| 丰县| 太白县| 上栗县| 松潘县| 沁源县| 彩票| 泌阳县| 安康市| 安吉县| 定安县| 屏东市| 湖州市| 历史| 乌兰浩特市| 双牌县| 正安县| 通渭县| 习水县| 吴旗县| 阳春市| 闵行区| 广灵县| 芜湖市|