關(guān)于view.post(r)和handler.post(r)的區(qū)別名挥?

參考:
https://blog.csdn.net/Kitty_Landon/article/details/79235418
https://blog.csdn.net/scnuxisan225/article/details/49815269
其實(shí)這兩個(gè)的主要區(qū)別是看目前界面有沒有顯示出來或者說在調(diào)用這兩個(gè)方法時(shí)乙嘀,view的dispatchAttachedToWindow方法有沒有執(zhí)行,如果已經(jīng)執(zhí)行過了咐刨,那么他們是沒啥區(qū)別的雕拼,都是利用Handler來發(fā)送Message到MessageQueue,如果dispatchAttachedToWindow還沒有執(zhí)行煞檩,那么他們是有區(qū)別的处嫌,最直觀的判斷就是我們可以在onCreate方法中利用view.post(runnable)來獲取view的寬高,但是無法利用handler.post(runnable)來獲取斟湃。

為什么在onCreate方法中可以利用view.post(runnable)獲取view的寬高熏迹?

看下源代碼:
View#post()

public boolean post(Runnable action) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler.post(action);
        }

        // Postpone the runnable until we know on which thread it needs to run.
        // Assume that the runnable will be successfully placed after attach.
        getRunQueue().post(action);
        return true;
    }

我們假設(shè)目前attachInfo為null(其實(shí)目前它就是為null的,哪兒賦值的凝赛,后面分析)

 /**
     * Returns the queue of runnable for this view.
     *
     * @return the queue of runnables for this view
     */
    private HandlerActionQueue getRunQueue() {
        if (mRunQueue == null) {
            mRunQueue = new HandlerActionQueue();
        }
        return mRunQueue;
    }

HandlerActionQueue#post()

public void postDelayed(Runnable action, long delayMillis) {
        final HandlerAction handlerAction = new HandlerAction(action, delayMillis);

        synchronized (this) {
            if (mActions == null) {
                mActions = new HandlerAction[4];
            }
            mActions = GrowingArrayUtils.append(mActions, mCount, handlerAction);
            mCount++;
        }
    }

可以看到注暗,在調(diào)用了view的post方法之后只是將runnable存放到了HandlerAction的數(shù)組中,并沒有去執(zhí)行墓猎,那么什么時(shí)候執(zhí)行呢捆昏?

存放在HandlerAction數(shù)組中的runnable什么時(shí)候執(zhí)行?

HandlerActionQueue#executeActions()

public void executeActions(Handler handler) {
       synchronized (this) {
           final HandlerAction[] actions = mActions;
           for (int i = 0, count = mCount; i < count; i++) {
               final HandlerAction handlerAction = actions[i];
               handler.postDelayed(handlerAction.action, handlerAction.delay);
           }

           mActions = null;
           mCount = 0;
       }
   }

在這個(gè)方法里面會(huì)調(diào)用handler來post之前存放的Runnable毙沾,看下這個(gè)方法是什么時(shí)候執(zhí)行的骗卜?


image.png

dispatchAttachedToWindow是什么時(shí)候執(zhí)行的呢?


image.png

我們知道ViewRootImpl的performTraversals會(huì)執(zhí)行view的measure搀军、layout膨俐、draw,大致是這樣:

host.dispatchAttachedToWindow()
...
performMeasure();
...
performLayout();
...
performDraw();

理一下:系統(tǒng)調(diào)用ViewRootImpl#performTraversals()方法罩句,performTraversals()方法調(diào)用host的dispatchAttachedToWindow()方法焚刺,host就是DecorView也就是View,接著在View的dispatchAttachedToWindow()方法中調(diào)用mRunQueue.executeActions()方法门烂,這個(gè)方法內(nèi)部會(huì)遍歷HandlerAction數(shù)組乳愉,利用Handler來post之前存放的Runnable。

問題來了屯远,dispatchAttachedToWindow方法是在performMeasure方法之前調(diào)用的蔓姚,既然在調(diào)用的時(shí)候還沒有執(zhí)行performMeasure來進(jìn)行測量,那么為什么在執(zhí)行完dispatchAttachedToWindow方法后就可以獲取到寬高呢慨丐?

因?yàn)锳ndroid系統(tǒng)的運(yùn)行完全是基于消息驅(qū)動(dòng)的坡脐。
在調(diào)用完dispatchAttachedToWindow方法之后,會(huì)將之前調(diào)用view.post(runnable)中的runnable取出來執(zhí)行房揭,這里的執(zhí)行其實(shí)是發(fā)送Message到MessageQueue备闲,等待Looper來調(diào)用執(zhí)行晌端,但是也得系統(tǒng)處理完上一個(gè)Message

而ViewRootImpl的performTraversals所處的環(huán)境正是一個(gè)Runnable對象,這個(gè)Runnable也是包裝成Message交給Handler來處理的恬砂,所以View.post(runnable)中的runnable執(zhí)行是要在performTraversals方法之后的咧纠,并非一調(diào)用dispatchAttachedToWindow就會(huì)執(zhí)行。

這個(gè)流程分析完了泻骤,我們回到View的post方法中

attachInfo什么時(shí)候被賦值的呢漆羔?

public boolean post(Runnable action) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler.post(action);
        }

        // Postpone the runnable until we know on which thread it needs to run.
        // Assume that the runnable will be successfully placed after attach.
        getRunQueue().post(action);
        return true;
    }
image.png

ViewRootImpl是什么時(shí)候被初始化的呢?
在Activity的onResume()方法之后狱掂。


image.png

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末可免,一起剝皮案震驚了整個(gè)濱河市葵诈,隨后出現(xiàn)的幾起案子扭粱,更是在濱河造成了極大的恐慌呐矾,老刑警劉巖族铆,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纲仍,死亡現(xiàn)場離奇詭異腐芍,居然都是意外死亡忧吟,警方通過查閱死者的電腦和手機(jī)养筒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門曾撤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人晕粪,你說我怎么就攤上這事挤悉。” “怎么了巫湘?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵装悲,是天一觀的道長。 經(jīng)常有香客問我尚氛,道長诀诊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任阅嘶,我火速辦了婚禮属瓣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘讯柔。我一直安慰自己抡蛙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布魂迄。 她就那樣靜靜地躺著粗截,像睡著了一般。 火紅的嫁衣襯著肌膚如雪捣炬。 梳的紋絲不亂的頭發(fā)上熊昌,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天怠晴,我揣著相機(jī)與錄音,去河邊找鬼浴捆。 笑死蒜田,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的选泻。 我是一名探鬼主播冲粤,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼页眯!你這毒婦竟也來了梯捕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤窝撵,失蹤者是張志新(化名)和其女友劉穎傀顾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體碌奉,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡短曾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赐劣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嫉拐。...
    茶點(diǎn)故事閱讀 39,965評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖魁兼,靈堂內(nèi)的尸體忽然破棺而出婉徘,到底是詐尸還是另有隱情,我是刑警寧澤咐汞,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布盖呼,位于F島的核電站,受9級特大地震影響化撕,放射性物質(zhì)發(fā)生泄漏几晤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一侯谁、第九天 我趴在偏房一處隱蔽的房頂上張望锌仅。 院中可真熱鬧,春花似錦墙贱、人聲如沸热芹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伊脓。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間报腔,已是汗流浹背株搔。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留纯蛾,地道東北人纤房。 一個(gè)月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像翻诉,于是被迫代替她去往敵國和親炮姨。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容