View的工作原理之Measure过程源码学习(一)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lin962792501/article/details/84854024

       在Android开发过程中,View控件的使用是最基本的技能,而自定义View技能的掌握也是非常重要的。这篇博文讲记录一下在读任玉刚老师的《Android开发艺术探索》一书中学习到的相关知识以及自己的一些收获。这里说明一点,在"View的工作原理之Measure过程源码学习"系列文章中,源码都是基于android-26这一套源码。

       我们都知道,在开发android的过程中,只要在布局文件中添加我们需要的View,然后在Activity的onCreate方法中的setContentView中将布局文件加载进来就可以在启动Activity之后,看到了我们添加的View。那么这里可以知道,View最后肯定是和Activity联系起来的,那么他们之间的是怎么联系起来的呢?通过源码发现,Activity和View之间是通过Window类的实现类PhoneWindow联系在一起的,每一个Activity拥有一个PhoneWindow的对象,而这些对象都通过WindowManager来管理,同时WindowManager也会为对应的PhoneWindow对象添加一个ViewRoot实现类ViewRootImpl的实例。ViewRootImpl实例就对应着Android的View视图层次结构的顶部,从ViewRoot这个类名大概也可以看出,它是整个试图的根,这一点有力的证据可以查看ViewRootImpl类的注释。

/**
 * The top of a view hierarchy, implementing the needed protocol between View
 * and the WindowManager.  This is for the most part an internal implementation
 * detail of {@link WindowManagerGlobal}.
 *
 * {@hide}
 */
public final class ViewRootImpl implements ViewParent,
        View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {
       
}

        知道了Activity、PhoneWindow以及ViewRoot与View展示有关之后,这里仍然需要了解一下DecorView。从上面可以看到ViewRootImpl并不是一个View,它不能够承载View,这就需要用到DecorView了,DecorView是整个View视图的顶级节点,也就是说,整个Android的View视图是从DecorView这里开始的,DecorView中包含两部分,一个是ActionBar,这个设置根据主题变化。另一个是ContentParent,我们通过setContentView方法设置的布局文件,最终就会被设置到ContentParent中。下图很好的展示了这几个部分之间的关系。

      下面我想从Android应用程序的启动过程开始,一直到Activity与PhoneWIndow的联系,ViewRootImpl与WindowManager的联系,ViewRootImpl与DecorView的联系过程,在源码中简略的走一遍。

       上面的流程图是我根据源码画的一个程序运行方法路线图,展示了Android应用程序的启动过程,标注红色字体1的路线是将Activity和PhoneWindow关联起来的部分;标注红色字体2的路线是DecorView的创建及将我们的View设置到DecorView;标注红色字体3的路线是将DecorView和PhoneWindow以及ViewRootImpl关联起来的部分。从上面的流程图可以看到,在handleResumeActivity中,将DecorView通过ViewRootImpl的setView方法将DecorView关联到View树,即ViewRootImpl中的mView就是DecorView。在ViewRootImpl中有一个方法performTraversals,在这个方法中,DecorView进行了measure,layout,draw三个过程,分别对应performMeasure,performLayout和performDraw三个方法,如下图所示。这里只需要详细了解performMeasure方法(是从哪个方法一路下来到达performMeasure方法,这个我还没有找到)。

        在performMeasure方法中,会调用DecorView的measure方法,measure方法是final类型,所以最终调用的是View中的measure方法,而View中的measure方法会调用实现类的onMeasure中的方法,也就是DecorView的onMeasure,在这个方法中会调用super.onMeasure,DecorView继承自FragmentLayout,FrameLayout继承自ViewGroup,因为ViewGroup是抽象类,因此他没有实现onMeasure方法,交由它的子类实现。所以最终会调用FrameLayout的onMeasure方法。在这个方法中,会循环遍历子元素经行它们的measure过程(具体代码查看FrameLayout的源码,这里就不贴了)。

猜你喜欢

转载自blog.csdn.net/lin962792501/article/details/84854024