欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

一、前言

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

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

二、post 在 7.0 的差異

2.1 post 方法的差異

前面提到,這個問題只出現(xiàn)在 Android 7.0 上。那么就先從源碼分析 Android 7.0 到底對 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() 到底干了什么?

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

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

它最終,還是調(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 都會有機(jī)會執(zhí)行到。

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

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

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

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

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

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

三、小結(jié)

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

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

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

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

總結(jié)

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

相關(guān)文章

  • JavaScript仿支付寶密碼輸入框

    JavaScript仿支付寶密碼輸入框

    那么今天我就用JavaScript代碼來實現(xiàn)這個效果吧,那么首先介紹一下整個的思路,首先我們先將確定輸入密碼的位數(shù),我的需求是5位,那么就用一個div標(biāo)簽包住5個input標(biāo)簽
    2015-12-12
  • JS使用Prim算法和Kruskal算法實現(xiàn)最小生成樹

    JS使用Prim算法和Kruskal算法實現(xiàn)最小生成樹

    這篇文章主要為大家詳細(xì)介紹了JS使用Prim算法和Kruskal算法實現(xiàn)最小生成樹,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • 如何自己實現(xiàn)JavaScript的new操作符

    如何自己實現(xiàn)JavaScript的new操作符

    new大家肯定都不陌生,單身沒有對象的時候就new一個,很方便。那么它在創(chuàng)建實例的時候,具體做了哪些操作呢?今天我們就來一起分析一下。
    2021-04-04
  • JavaScript實現(xiàn)手寫循環(huán)滑動效果

    JavaScript實現(xiàn)手寫循環(huán)滑動效果

    最近一直在做業(yè)務(wù),遇到一個需求是頁面頂部需要展示圖片,可以拖動,拖動到最后一張的時候需要無縫切換到第一張,從而實現(xiàn)循環(huán)滑動,所以本文就來和大家分享一下實現(xiàn)方法
    2023-05-05
  • JavaScript中常見的獲取當(dāng)前日期方法

    JavaScript中常見的獲取當(dāng)前日期方法

    在我們開發(fā)的許多應(yīng)用程序都會用到某種日期功能,無論是內(nèi)容的創(chuàng)建日期還是活動的時間戳等等,這篇文章主要給大家介紹了關(guān)于JavaScript中常見的獲取當(dāng)前日期方法,需要的朋友可以參考下
    2024-06-06
  • 利用JS實現(xiàn)機(jī)器人總動員小游戲

    利用JS實現(xiàn)機(jī)器人總動員小游戲

    這篇文章主要介紹了如何利用HTML+CSS+JS編寫一個機(jī)器人總動員小游戲,代碼簡單易懂對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-11-11
  • Math.js解決js中小數(shù)精度丟失問題

    Math.js解決js中小數(shù)精度丟失問題

    在JavaScript中進(jìn)行小數(shù)運算時,會容易出現(xiàn)精度丟失的問題,例如在進(jìn)行兩個小數(shù)相加時,結(jié)果并不是預(yù)期的精確值,而是一個近似值,,使用第三方庫Math.js可以避免精度丟失的問題,本文導(dǎo)入Math.js庫和使用Math.js的方法來進(jìn)行小數(shù)運算,同時還可以指定格式來保留小數(shù)位數(shù)
    2023-12-12
  • 基于Bootstrap+jQuery.validate實現(xiàn)表單驗證

    基于Bootstrap+jQuery.validate實現(xiàn)表單驗證

    這篇文章主要為大家詳細(xì)介紹了基于Bootstrap+jQuery.validate實現(xiàn)表單驗證,感興趣的小伙伴們可以參考一下
    2016-05-05
  • javascript遞歸函數(shù)定義和用法示例分析

    javascript遞歸函數(shù)定義和用法示例分析

    這篇文章主要介紹了javascript遞歸函數(shù)定義和用法示例分析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • JavaScript對象學(xué)習(xí)小結(jié)

    JavaScript對象學(xué)習(xí)小結(jié)

    JavaScript 中的所有事物都是對象:字符串、數(shù)值、數(shù)組、函數(shù).幾乎用到的每個js都離不開它的js對象。此外,JavaScript 允許自定義對象,下面跟著小編學(xué)習(xí)javascript對象學(xué)習(xí)小結(jié),需要的朋友可以參考下
    2015-09-09

最新評論