1慨默、activity生命周期跟view繪制流程的觸發(fā)順序
onCreate ->onStart -> onResume -> makeVisible
windowManagerImpl.addView->windowManagerGlobal.addView -> viewRootImpl.setView ->viewRootImpl.requestLayout() -> viewRootImpl.scheduleTraversals()
在scheduleTraversals()方法中先用handler發(fā)送一個(gè)同步障礙物消息强岸,接著再發(fā)送一個(gè)異步消息遮婶,當(dāng)looper循環(huán)處理到這個(gè)異步消息的時(shí)候就會調(diào)用doTraversal()方法,在doTraversal()方法中會刪除掉同步障礙物消息,并且執(zhí)行performTraversals()方法
performTraversals()方法相關(guān)執(zhí)行邏輯:
1)getRunQueue().executeActions(mAttachInfo.mHandler);
2)performMeasure() 測量
3)performLayout() 布局
4)performDraw() 繪制
getRunQueue().executeActions(mAttachInfo.mHandler)代碼邏輯
解析:將actions(view.post方法的runnable參數(shù)集合)使用handler post到消息隊(duì)列中,并將mActions變量置空,當(dāng)這些runnable執(zhí)行的時(shí)候就可以拿到view的尺寸信息仔粥,因?yàn)檫@些runnable是在繪制流程完成后才執(zhí)行的。
2蟹但、view.post方法解析
在view還沒attachToWindow的時(shí)候躯泰,mAttachInfo為null,會執(zhí)行g(shù)etRunQueue().post(action);
getRunQueue().post(action)方法解析:
可以看出只是把runnable存儲起來矮湘,并沒立即執(zhí)行斟冕。
結(jié)論:
1、在Activity的生命周期onCreate()缅阳、onStart()磕蛇、onResume()方法中通過view.post(Runnable r)是可以獲得view尺寸信息的景描;
2、在Activity的生命周期onCreate()秀撇、onStart()超棺、onResume()方法中通過handler.post(Runnable r)方法是不能獲取到view尺寸信息的,因?yàn)檫@些runnable會在view繪制流程之前執(zhí)行呵燕。
關(guān)于同步障礙物消息跟異步消息請參考《android同步障礙物消息和異步消息》這篇文章
如有分析不正確的地方棠绘,請大神們指正