Android葵花宝典Android进阶Android进阶之旅

Android Render(一)Activity窗口构成和绘制

2017-10-11  本文已影响636人  生椰拿铁锤

阅读者三篇Android绘制文章,会让你对理解Android绘制有帮助:


一、Activity窗口构成

这里我们会介绍到ActivityPhoneWindowDecorViewViewRootImplWindowManagerImplWindowManagerGlobalActivityThreadSurface,关于Activity窗口有很多方面可讲,我这里只侧重于Activity窗口的Render方面来讲解。先来两张张大家早已经烂熟于心的图:

1-1 Activity启动流程图 1-2 Activity构成图

一个Activity的构成有,ActivityPhoneWindowDecorView,再加上DecorView里面的TitleBar和我们填充的content内容,这些还Activity构成需要的具体类,不是一些辅助类,其实还有ViewRootImplWindowManagerImplWindowManagerGlobalActivityThread这几个不可见的辅助类,虽然是Activity构成可见UI界面没用到,但是这几个辅助类都是直接或者间接负责了Activity的构建和绘制的。下面我按照我的理解来一一介绍这些类的作用和被创建时机,有不对的地方还请大家指正:

二、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窗口创建的流程我们可以知道:

三、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绘制流程与源码分析

上一篇 下一篇

猜你喜欢

热点阅读