从UI绘制了解View,Activity,WMS,SurfaceFilnger之间的关系和作用

一,什么是DecorView

1,在Android中所有的界面都是由无数的View组成。
2,Android官方定义,最顶层的View是DecorView,该DecorView对象是所有应用窗口(Activity界面)的根View。
3,DecorView是PhoneWindow的内部类,FrameLayout的子类,是对FrameLayout进行功能的修饰(所以叫DecorView),是所有应用窗口的根View。
4,从根视图DecorView开始都是继承View的,所以视图的绘制从这个DecorView开始依次递归(ViewGroup -> View)调用:
measure,layout,draw

二,Activity的setContentView准备View流程

1,Activity在创建时会在onCreat方法中调用setConentView。
2,Activity的setConentView实际调用的是getWindow的setConentView,最终调用PhoneWindow的setConentView.
3,在此方法中会去判断mContentParent是否为空,为空的话会去执行installDecor,不为空的话会先执行mContentParent.removeAllView(),再去添加视图。
4,在installDecor中mContentParent会去调用generateLayout
5,在generateLayout中经过不断对LocalFeatures判定,对layoutResource进行赋值,这是在给顶层主题选择不同view做一个基础布局。
6,layoutResource就是不同主题的基础布局ID,官方根据你主题的不同去加载一个layout。
7,当获取到layoutResource后,mDecor就会去调用onResourceLoaded方法,传入layoutInflater和layoutResource参数进去。
8,接着调用LayoutInflater的inflater方法进行xml解析,用的pull解析。
9,将xml里的数据一个个提取出来之后,调用creatViewFromTag,接着调用creatView,在creatView中通过反射,把相关文件构建程一个一个的view。
10,这样mDecor就构建好了,这里的mDecor就是整个View。
11,这时通过findViewByID传入content这个ID,就会获取到一个名为mCotentParent的ViewGroup,这个就是用户自己的View,也是mDecor内部提供给用户布局的组件。
12,mDecor使用rInfaterChildren递归调用初始化顶层mContentParent,然后将相关的下级网上级添加,从而加载所有View。
13,View准备基本完毕。

三,DecorView加载到窗口流程

1,在ApplicationThread中刚创建Activity时,会调用Activity的attach方法。
2,在attach方法中主要做了三件事:(1)构建一个窗体对象PhoneWondow;(2)构建一个WindowManager管理对象;(3)构建一个专门与WMS交互的对象WindowManagerGlobal。3,在Activity的onResume方法中,DecorView会add到WindowManager中,并做了强转成WindowManagerGlobal,并add到Global上,最终交给ViewRootImpl进行管理。
4,ViewRootImpl是View的最高层级,是所有View的根。ViewRootImpl实现了View和WindowManger之间所需要的协议。ViewRootImpl的创建过程是从WindowManagerImpl中开始的。View的测量,布局,绘制以及上屏,都是从ViewRootImpl中开始的。
5,总结:在Activity中的setContentView方法中的View最终会被添加到Window对象中的DecorView中,也就是说一个Window中对应着一个View。这个View是被RootImpl操作的。
WindowManager就是入口,通过WindowManager的addView添加一个Window,然后就会创建一个ViewRootImpl,来对view进行操作,最后将view渲染到屏幕的窗口上。
例如Activity中,在onResume执行完成后,就会获取Window中的DecorView,然后通过WindowManager把DecorView添加到窗口上,这个过程中是由RootViewImpl来完成测量,绘制等操作的。

四,setContentView流程简述:

1,调用PhoneWindow.setContentView(resouseID)
2,PhoneWindow中:创建mDector:窗体上的整个View:里面有官方的主题布局+用户自己的布局;
3,PhoneWindow中:创建mContentParent:官方主题布局中提供给用户装载布局的容器:id为content;
4,调用mLayoutInflater.inflater(resouseID,mContentParent):
5,解析用户的布局xml
6,递归调用:解析根布局,通过反射创建根布局;解析子view,通过反射创建view;
7,最后根据PhoneWindow中的mContentParent加载用户的根布局
8,提交view数据
ps:这里递归调用,如果层级嵌套太多,会导致栈溢出;因为递归调用不会释放栈;
ViewRootImpl单例,管理所有View绘制策略
注意onCreat.setContentView后数据已经解析并实例化了。

五,绘制加载过程简述:

1,当在onResume方法时
2,会调用windowImpl中的mGlobal.addView(view)
3,addView中创建ViewRootImpl root = new ViewRootImpl();
4,root.setView(view);
5,在setView中调用requestLayout()
6,requestLayout()请求绘制,编舞者出场

六,Choreography编舞者:负责管理帧率节奏

1,在内部维护了一个Handler和Looper,保证绘制发生在UI主线程:
looper.myLooper == mLooper判断是否是主线程,是的话去调同步绘制信号,不是的话发送消息,走主线程去调用同步绘制信号;
2,走native层请求垂直同步信号,实际是找底层驱动要上次绘制的时间;
3,请求到垂直同步信号后回调onVsync;
4,走doFrame去逻辑管控,判断当前时间离上次绘制的时间是否大于1帧的时间(16.66)毫秒就跳帧,若小于16.66毫秒就再次请求垂直同步信号,防止重叠;
5,执行callback,让ViewRootImpl去真正绘制,调用ViewRootImpl.performTraversals()

七,真正的绘制流程:

1,在ViewRootImpl.performTraversals()中调用relayoutWindow()
2,创建用户java层的surface:只有用户提供的画面数据
3,创建native层的surface:包含用户提供的画面数据(java层的surface) + 系统的画面数据(状态栏,电池,wifi等等)
4,创建完surface后:依次调用performMeasure(对应view的onMeasure)、performLayout(onLayout)、performDraw(onDraw);
5,在performDraw中:
6,将view的数据传递至native层的surface
7,surface中的canvas记录数据
8,生成bitmap图像数据(此时数据是在surface中);
9,将surface数据放在队列中;生成者消费者模式;
10,通知surfacefliger进程去队列中取surface数据;
11,surfacefliger拿到不同的surface,进行融合,生成bitmap数据;
12,将bitmap数据放入framebuffer中,进行展示

八,setContentView绘制全流程总结:

1,由Launcher或Activity中发起调用;
2,AMS管理的是配置信息数据;
3,具体的对象创建过程是在ActivityThread中完成
4,由AMS的startActivity触发resume生命周期,在resume生命周期中对于View数据推送至WindowManager进行管理,同时生成一个ViewRootImpl对象对于所有的View数据进行绘制管理;
5,ViewRootImpl中依赖于编舞者工具对于绘制进行控制,一般为60FPS;
6,具体绘制由ViewRootImpl中的performTraversals进行具体绘制操作;
7,绘制完成后,因为每一个View都是一个surface,通过为surfacefliger提供surface完成每个View的绘制后;
8,由WMS统一协调每个VIEW的层级,尺寸,布局等;
9,最终交由surfacefliger进行帧合成,完成整体界面输出;
10,底层由opengl完成

九,WMS的主要角色及其作用

1,window:是一个抽象类,具体实现类为PhoneWindow,它对View进行管理。Window是View的容器,View是Window的具体表现内容。
2,windowManager:是一个接口类,继承自接口ViewManager,从他的名称就知道它是用来管理Window的,它的实现类为WindowManagerImpl;
3,WMS:是窗口的管理者,它负责窗口的启动,添加和删除。另外窗口层架的大小也是由它进行管理的。它是数据的管理者,另外它也是与surfaceFlinger的通信的协调者。

相关推荐

  1. 【知识---ubuntudebian之间关系

    2024-04-08 05:38:01       26 阅读
  2. 数据库 数据库之间关系

    2024-04-08 05:38:01       19 阅读
  3. 关于python变量作用域,你了解多少?

    2024-04-08 05:38:01       38 阅读
  4. 自定义一个作用域开始来了解SpringBean作用

    2024-04-08 05:38:01       15 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-08 05:38:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-08 05:38:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-08 05:38:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-08 05:38:01       18 阅读

热门阅读

  1. 【GDB】GDB解CORE文件

    2024-04-08 05:38:01       15 阅读
  2. 这家城商行下线京东金融、滴滴互联贷款业务

    2024-04-08 05:38:01       13 阅读
  3. Healthcare医疗健康领域常见的几个单词

    2024-04-08 05:38:01       11 阅读
  4. 汽车电子行业知识:UWB技术及应用

    2024-04-08 05:38:01       15 阅读
  5. 文库配置转换为静态HTML | 魔众文库系统

    2024-04-08 05:38:01       13 阅读
  6. html表单1:表单基础

    2024-04-08 05:38:01       10 阅读
  7. 【Verilog】工业级RTL代码风格推荐

    2024-04-08 05:38:01       13 阅读