android 中一种获取view尺寸的方式及原理分析

1、activity生命周期跟view绘制流程的触发顺序

onCreate ->onStart -> onResume -> makeVisible

windowManagerImpl.addView->windowManagerGlobal.addView -> viewRootImpl.setView ->viewRootImpl.requestLayout() -> viewRootImpl.scheduleTraversals()

在scheduleTraversals()方法中先用handler发送一个同步障碍物消息,接着再发送一个异步消息,当looper循环处理到这个异步消息的时候就会调用doTraversal()方法,在doTraversal()方法中会删除掉同步障碍物消息,并且执行performTraversals()方法

performTraversals()方法相关执行逻辑:

1)getRunQueue().executeActions(mAttachInfo.mHandler);

2)performMeasure() 测量

3)performLayout() 布局

4)performDraw() 绘制

getRunQueue().executeActions(mAttachInfo.mHandler)代码逻辑

解析:将actions(view.post方法的runnable参数集合)使用handler post到消息队列中,并将mActions变量置空,当这些runnable执行的时候就可以拿到view的尺寸信息,因为这些runnable是在绘制流程完成后才执行的。

2、view.post方法解析

在view还没attachToWindow的时候,mAttachInfo为null,会执行getRunQueue().post(action);

getRunQueue().post(action)方法解析:

可以看出只是把runnable存储起来,并没立即执行。

结论:

1、在Activity的生命周期onCreate()、onStart()、onResume()方法中通过view.post(Runnable r)是可以获得view尺寸信息的;

2、在Activity的生命周期onCreate()、onStart()、onResume()方法中通过handler.post(Runnable r)方法是不能获取到view尺寸信息的,因为这些runnable会在view绘制流程之前执行。

关于同步障碍物消息跟异步消息请参考《android同步障碍物消息和异步消息》这篇文章

如有分析不正确的地方,请大神们指正

你可能感兴趣的:(android 中一种获取view尺寸的方式及原理分析)