Android Render(一)Activity窗口构成和制图解析


阅读者三篇Android绘制文章,会让你对明白Android绘制有援助:


一、Activity窗口构成

那里大家会介绍到ActivityPhoneWindowDecorViewViewRootImplWindowManagerImplWindowManagerGlobalActivityThreadSurface,关于Activity窗口有无数地点可讲,我那里只侧重于Activity窗口的Render方面来讲学。先来两张张我们早已经烂熟于心的图:

1-1 Activity起始流程图

1-2 Activity构成图

一个Activity的三结合有,ActivityPhoneWindowDecorView,再添加DecorView里面的TitleBar和大家填充的content内容,那些还Activity构成需求的具体类,不是一对扶助类,其实还有ViewRootImplWindowManagerImplWindowManagerGlobalActivityThread那多少个不可知的接济类,纵然是Activity构成可知UI界面没用到,可是那多少个援救类都是直接或者间接承担了Activity的打造和制图的。上面我依照自己的驾驭来挨家挨户介绍那个类的法力和被创立时机,有不规则的地点还请大家指正:

  • Activity:一个两次三番ContextThemeWrapper的类,继承自ContextThemeWrapper那么意味着,通过Activity可以访问当前包的资源(getResources、getAssets)和起步其余零件(Activity、Service、布罗德cast)以及获得种种劳动(getSystemService),并且定义了如今Activity的Theme宗旨项目
    ,关于Context的诠释请看:http://www.cnblogs.com/android100/p/Android-Context.html
    并且唯有成立了一个Activity才会成立前边的PhoneWindow、DecorView、ViewRootImpl、WindowManagerImpl、和Surface这个类。我那边并没说ActivityThread类,ActivityThread是Android应用的主线程(UI线程),一个使用进度才有一个UI线程。也尚无说WindowManagerGlobal类,那一个类用了多少个数组管理一个利用进度内装有Activity的DecorView和ViewRootImpl以及WindowManager对应提到的。WindowManagerGlobal是一个单例的类,一个用到进程内也唯有一个。不过WindowManagerImpl是每一个Activity都有一个的。Activity是在ActivityThread的performLaunchActivity方法中用ClassLoader类加载器成立出来的。

  • PhoneWindow:
    一个持续于肤浅类Window的类,也是Window的绝无仅有兑现类。在Activity中PhoneWindow处在一级地点,可是PhoneWindow是一个不可知的类,PhoneWindow内的DecorView才是大家看得出的UI布局,不过大家可知的UI布局为何要卷入一层PhoneWindow列?经过我的频仍查看源代码和推敲,我发觉PhoneWindow担负了Activity
    UI界面超级布局DecorView的创立,PhoneWindow保存了window
    attributes即窗口布局属性参数,保存了与WindowManager瑟维斯进程通信的IBinder
    (取名token)方便去系统WindowManagerService进度通信,并且负责了用户Key和Touch事件的散发,可是PhoneWindow分发事件也是付诸了DecorView来形成的。除了大家Activity在setContent时PhoneWindow创立了DecorView,好像PhoneWindow并从未承担太多的Render的轩然大波。看源码确实就是如此啊!,其实确实的Render操作都在ViewRootImpl类中。PhoneWindow是在Activity的attach方法中new出来的。

  • WindowManagerImpl:
    见名知意,就是管制Window的,在此间就是管制PhoneWindow的,每一个Activity都有一个和谐的WindowManagerImpl来管理自己的PhoneWindow,WindowManagerImpl其实是用来治本PhoneWindow里面的DecorView的,也可能是DecorView级其他其余的View,还有就是WindowManagerImpl是用来跟一个App全局的PhoneWindow管理器WindowManagerGlobal通讯的,添加、移除和更新DecorView层级的View时WindowManagerImpl会调用WindowManagerGlobal中的方法来拓展全局管理。WindowManagerImpl是在Activity的attach方法中new
    PhoneWindow后调用mWindow.setWindowManager方法创造的,其中间是调用setWindowManager的createLocalWindowManager方法new出来的。

  • DecorView:
    是一个ViewGroup,继承自FrameLayout,是大家来看的UI界面的头等容器,DecorView是PhoneWindow的积极分子。DecorView除开是Activity界面的一等容器以外,DecorView依然key和touch事件从上向下真正分发初叶的源头。事件分发从Activity—》PhoneWindow—》DecorView—》层层向下分发到大家的界面底层。DecorView其实在广大地点都会创制,PhoneWindow内部的getDecorView方法被调用时,如若内部的积极分子变量mDecor为空的话,就会调用installDecor()方法去创立一个DecorView,最终new
    一个DecorView重回,有限支撑调用PhoneWindow的getDecorView获取
    DecorView时世代不会为空。
    自身看代码发现PhoneWindow的DecorView第一遍调用暴发在ActivityThread内的handleResumeActivity方法中,handleResumeActivity方法中还有一个很主要的步子,就是调用了WindowManagerImpl的addView(DecorView,WindowManager.LayoutParams
    )方法,进去创制了一个跟DecorView关联的ViewRootImpl类。

  • ViewRootImpl:是一个落到实处了ViewParent接口的final类。我眼前说到了,ViewRootImpl紧即使负担Activity的界面Render绘制的,负责整个窗口界面的ViewTree的绘图更新。ViewRootImpl要肩负DecorView的绘图,那么ViewRootImpl就须要有所当前Activity的DecorView的引用,是的,的确如此,前面介绍DecorView的制造的时候自己说到了DecorView第三回创设暴发在ActivityThread内的handleResumeActivity方法中,handleResumeActivity方法中还有一个很要紧的步子,就是调用了WindowManagerImpl的addView(DecorView,WindowManager.LayoutParams
    )方法,进去创设了一个跟DecorView关联的ViewRootImpl类。WindowManagerImpl的addView方法其实调用了WindowManagerGlobal的addView方法,在这一个措施中成立了ViewRootImpl,并且在那些艺术中调用了ViewRootImpl的setView方法,使ViewRootImpl持有DecorView的引用。并且把已毕了ViewParent接口的友善设置成了DecorView的Parent。那样ViewRootImpl就足以妄作胡为地操作DecorView了。其实自己在调用普通view的invalidate()刷新时,其实是因而层层Parent寻找,最后调用了最顶层的ParentViewRootImpl的invalidate()来判定和处理每趟的UI界面刷新的。

  • Surface:一个完结了Parcelable接口的类,对Parcelable接口不了解的,请看本身前边的Binder通讯的稿子:Android
    IPC之AIDL看这一篇还不够
    Surface是土生土长图像缓冲区(raw
    buffer)的一个句柄,而原来图像缓冲区是由显示器图像合成器(screen
    compositor)管理的。得到了Surface其一句柄就足以得到其中的Canvas、原生缓冲器以及此外地点的情节。所以说Surface是生成Canvas的地点,具体就是调用lockCanvas方法获得Canvas。至于Canvas、Paint
    和Bitmap的关系我那里就不讲了,后边会有成文来讲那么些。Surface是ViewRootImpl的一个final成员变量,伴随ViewRootImpl的始建默认就new一个出去了,可是此时的Surface是一个空的,里面是向来不内容的。Surface的数量填充是要跟WindowManagerService相互的,应用进程端Binder文告WindowManagerService进度端创立一个Surface对象,最终是将WindowManagerService进程端的
    Surface对象传递到应用进程端并赋值给使用进程的Surface对象,那样窗口可以应用Surface来绘制UI了。
    因为Surface对象要夸进度传递,所以Surface要达成Parcelable接口。更详细的牵线有关窗口的Surface创立请看锤子科学和技术开创者老罗的:Android应用程序窗口(Activity)的绘图表面(Surface)的创制进度分析

二、Activity窗口创设流程

上边的名词介绍其实就是坚守窗口的创始流程的相继来讲的,不过单单是文字不够直观,上边以箭头加方法名的样式表现一下,源码分析流程基于Android7.1

/**1*/ ApplicationThread的onTransact方法接收到SystemServer进程的SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION启动Activity的Binder信息
                ↓
/**2*/ ApplicationThread.scheduleLaunchActivity() //
                ↓
/**3*/ ActivityThread.scheduleLaunchActivity() //安排启动Activity
                ↓
/**4*/ ActivityThread.handleLaunchActivity()  //处理启动Activity
                ↓
/**5*/ ActivityThread.handleResumeActivity() // Activity 的Resume会使DecorView跟ViewRootImpl关联
                ↓
/**6*/ WindowManagerGlobal.addView() //全局保存窗口的信息
                ↓
/**7*/ ViewRootImpl.setView()  //使DecorView和ViewRootImpl关联并绘制界面
                ↓
/**8*/ ViewRootImpl.requestLayout() //请求绘制ViewTree
                ↓
/**9*/ ViewRootImpl.scheduleTraversals() // 安排遍历 
                ↓
/**10*/ ViewRootImpl.doTraversal() //
                ↓
/**11*/ ViewRootImpl.performTraversals() //执行遍历 会根据情况调用relayoutWindow performMeasure performLayout performDraw 等方法 这四个方法跟绘制是紧密相关的
                ↓
/**12*/ ViewRootImpl.relayoutWindow() //窗口第一次创建或者是窗口大小有变化并且窗口可见就会调用此方法 
                ↓
/**13*/ ViewRootImpl.mWindowSession.relayout() //binder通信通知WindowManagerService创建一个跟应用端关联的Surface
                ↓
/**14*/ ViewRootImpl调用performMeasure performLayout performDraw方法绘制UI

实在第五步ActivityThread.handleResumeActivity()方法内会调用到WindowManagerGlobal.addView()方法把窗口绘制完结,紧接着就调用到了activity.makeVisible()方法,其实就是突显出DecorView,因为DecorView创制绘制前是被设置成了INVISIBLE的,Activity中的makeVisible方法就是把绘制完毕的DecorView突显出来了:

    void makeVisible() {
        if (!mWindowAdded) {
            ViewManager wm = getWindowManager();
            wm.addView(mDecor, getWindow().getAttributes());
            mWindowAdded = true;
        }
        mDecor.setVisibility(View.VISIBLE); //把DecorView设置成可见的
    }

从那之后大家就看出Activity界面上的UI了。

关于Activity的绘图表面(Surface)的创办进程本身还想多说一下,以及Surface跟Activity的照应关系。

Surface是ViewRootImpl的一个final成员变量,伴随ViewRootImpl的创设默许就new一个出去了,但是此时的Surface是一个空的,里面是一向不内容的。Surface的数据填充是要跟WindowManagerService交互的,应用进度端Binder公告WindowManagerService进度端创立一个Surface对象,最终是将WindowManagerService进度端的
Surface对象传递到应用进度端并赋值给采取进度的Surface对象,那样窗口可以使用Surface来绘制UI了。
因为Surface对象要夸进度传递,所以Surface要促成Parcelable接口。

从Activity窗口创造的流水线大家可以精通:

  • 每一个应用程序窗口都对应该五个Java层的Surface对象,其中一个是在WindowManagerService服务那旁边开立的,而除此以外一个是在应用程序进度那旁边成立的。

  • 在WindowManagerService服务这旁边制造的Java层的Surface对象在C++层关联有一个SurfaceControl目的,用来安装使用窗口的性能,例如,大小和地点等。

  • 在应用程序进度那旁边创办的ava层的Surface目标在C++层关联有一个Surface对象,用来绘制应用程序窗品的UI。

三、Activity窗口组件之间的照应关系

一个设施有一个WindowManagerService进程 有一个SystemServer进程

一个App有一个WindowManagerGlobal类 有一个ActivityThread类
有一个ApplicationThread类

一个App可以有成百上千个Activity

一个 Activity有一个PhoneWindow类

一个PhoneWindow类有一个ViewRootImpl类

一个PhoneWindow类有一个WindowManagerImpl类

一个ViewRootImpl类有一个Surface类 有一个DecorView类

用一张图表示:

Android设备构成图

参照文章:
Android应用程序窗口(Activity)的绘图表面(Surface)的开创进度分析
从源码看invalidate和requestLayout的不一样
Android
Render序列规划篇

Android应用层View绘制流程与源码分析

相关文章