android宝典view必考知识点总结

author author     2023-04-10     399

关键词:

参考技术A 我们知道,Activity 是在 ActivityThread 的 performLaunchActivity 中进行创建的,在创建完成之后就会调用其 attach 方法,它是先于 onCreate、onStart、onResume 等生命周期函数的,因此将 attach 方法作为这篇文章主线的开头:

attach() 方法就是 new 一个 PhoneWindow 并且关联 WindowManager。

接下来就到了 onCreate 方法:

这一步就是把我们的布局文件解析成 View 塞到 DecorView 的一个 id 为 R.id.content 的 ContentView 中,DecorView 本身是一个 FrameLayout,它还承载了 StatusBar、NavigationBar 。

然后在 handleResumeActivity 中,通过 WindowManager 的 addView 方法把 DecorView 添加进去,实际实现是 WindowManagerImpl 的 addView 方法,它里面再通过 WindowManagerGlobal 的实例去 addView 的,在它里面就会 new 一个 ViewRootImpl,也就是说最后是把 DecorView 传给了 ViewRootImpl 的 setView 方法。ViewRootImpl 是 DecorView 的管理者,它负责 View 树的测量、布局、绘制,以及通过 Choreographer 来控制 View 的刷新。

WMS 是所有 Window 窗口的管理员,负责 Window 的添加和删除、Surface 的管理和事件派发等等,因此每一个 Activity 中的 PhoneWindow 对象如果需要显示等操作,就必须要与 WMS 交互才能进行。

在 ViewRootImpl 的 setView 方法中,会调用 requestLayout,并且通过 WindowSession 的 addToDisplay 与 WMS 进行交互。WMS 会为每一个 Window 关联一个 WindowStatus。

SurfaceFlinger 主要是进行 Layer 的合成和渲染。

在 WindowStatus 中,会创建 SurfaceSession,SurfaceSession 会在 Native 层构造一个 SurfaceComposerClient 对象,它是应用程序与 SurfaceFlinger 沟通的桥梁。

经过步骤四和步骤五之后,ViewRootImpl 与 WMS、SurfaceFlinger 都已经建立起连接,但此时 View 还没显示出来,我们知道,所有的 UI 最终都要通过 Surface 来显示,那么 Surface 是什么时候创建的呢?

这就要回到前面所说的 ViewRootImpl 的 requestLayout 方法了,首先会 checkThread 检查是否是主线程,然后调用 scheduleTraversals 方法,scheduleTraversals 方法会先设置同步屏障,然后通过 Choreographer 类在下一帧到来时去执行 doTraversal 方法。简单来说,Choreographer 内部会接受来自 SurfaceFlinger 发出的 Vsync 垂直同步信号,这个信号周期一般是 16ms 左右。doTraversal 方法首先会先移除同步屏障,然后 performTraversals 真正进行 View 的绘制流程,即调用 performMeasure、performLayout、performDraw。不过在它们之前,会先调用 relayoutWindow 通过 WindowSession 与 WMS 进行交互,即把 Java 层创建的 Surface 与 Native 层的 Surface 关联起来。

接下来就是正式绘制 View 了,从 performTraversals 开始,Measure、Layout、Draw 三步走。

第一步是获取 DecorView 的宽高的 MeasureSpec 然后执行 performMeasure 流程。MeasureSpec 简单来说就是一个 int 值,高 2 位表示测量模式,低 30 位用来表示大小。策略模式有三种,EXACTLY、AT_MOST、UNSPECIFIED。EXACTLY 对应为 match_parent 和具体数值的情况,表示父容器已经确定 View 的大小;AT_MOST 对应 wrap_content,表示父容器规定 View 最大只能是 SpecSize;UNSPECIFIED 表示不限定测量模式,父容器不对 View 做任何限制,这种适用于系统内部。接着说,performMeasure 中会去调用 DecorView 的 measure 方法,这个是 View 里面的方法并且是 final 的,它里面会把参数透传给 onMeasure 方法,这个方法是可以重写的,也就是我们可以干预 View 的测量过程。在 onMeasure 中,会通过 getDefaultSize 获取到宽高的默认值,然后调用 setMeasureDimension 将获取的值进行设置。在 getDefaultSize 中,无论是 EXACTLY 还是 AT_MOST,都会返回 MeasureSpec 中的大小,这个 SpecSize 就是测量后的最终结果。至于 UNSPECIFIED 的情况,则会返回一个建议的最小值,这个值和子元素设置的最小值以及它的背景大小有关。从这个默认实现来看,如果我们自定义一个 View 不重写它的 onMeasure 方法,那么 warp_content 和 match_parent 一样。所以 DecorView 重写了 onMeasure 函数,它本身是一个 FrameLayout,所以最后也会调用到 FrameLayout 的 onMeasure 函数,作为一个 ViewGroup,都会遍历子 View 并调用子 View 的 measure 方法。这样便实现了层层递归调用到了每个子 View 的 onMeasure 方法进行测量。

第二步是执行 performLayout 的流程,也就是调用到 DecorView 的 layout 方法,也就是 View 里面的方法,如果 View 大小发生变化,则会回调 onSizeChanged 方法,如果 View 状态发生变化,则会回调 onLayout 方法,这个方法在 View 中是空实现,因此需要看 DecorView 的父容器 FrameLayout 的 onLayout 方法,这个方法就是遍历子 View 调用其 layout 方法进行布局,子 View 的 layout 方法被调用的时候,它的 onLayout 方法又会被调用,这样就布局完了所有的 View。

第三步就是 performDraw 方法了,里面会调用 drawSoftware 方法,这个方法需要先通过 mSurface lockCanvas 获取一个 Canvas 对象,作为参数传给 DecorView 的 draw 方法。这个方法调用的是 View 的 draw 方法,先绘制 View 背景,然后绘制 View 的内容,如果有子 View 则会调用子 View 的 draw 方法,层层递归调用,最终完成绘制。

完成这三步之后,会在 ActivityThread 的 handleResumeActivity 最后调用 Activity 的 makeVisible,这个方法就是将 DecorView 设置为可见状态。

https://juejin.im/post/5c67c1e16fb9a04a05403549

https://juejin.im/post/5bf16ff5f265da6141712acc

android高频面试之必考java基础(代码片段)

如果大家去面Android客户端岗位,那么必问Java基础和Kotlin基础,所以,我打算花3,4篇文章的样子来给大家总结下Android面试中会问到的一些Java基础知识。1,面向对象和面向过程的区别面向过程:面向过程性能比面向对象高。因... 查看详情

android面试宝典

AndroidAndroid基础知识Android内存泄漏总结Android内存泄漏分析及总结Android性能优化ListView详解RecyclerView和ListView异同Asynctask源码分析插件化技术自定义控件事件分发机制ANR问题Art和Dalvik的区别Android关于OOM的解决方案FragmentActivity&Fr... 查看详情

android面试宝典

Java知识点包括:接口与抽象的使用及区别,多线程,socket基础,集合类,也有个别公司考察定义,很无语.C/C++知识点包括:指针的移动,排序算法,链表,有时还会有二叉树的遍历或图的遍历.1.Android 手机操作系统的四层架构? Application... 查看详情

接口测试基本理论知识总结(书籍推荐:自动化测试实战宝典)

什么是接口测试?接口测试主要检测系统中模块与模块中,交互的点。重点是检查数据的交换、传递,以及模块之前的联系关系。测试策略接口测试可以分为,接口功能测试,接口性能测试(压测),接口稳定性测试(某一个时... 查看详情

android面试题总结之android进阶(代码片段)

Android之美从0到1之Android进阶(二)在上一章节中《Android之美从0到1之Android进阶(一)》中我们已经理解了一些View的基本知识并且知道如何自定义View。那么本章节将继续深入理解View,关于View的绘制流程,... 查看详情

android面试题总结之android进阶(代码片段)

Android之美从0到1之Android进阶(二)在上一章节中《Android之美从0到1之Android进阶(一)》中我们已经理解了一些View的基本知识并且知道如何自定义View。那么本章节将继续深入理解View,关于View的绘制流程,... 查看详情

刚参加完阿里android开发岗面试:一面+二面+三面+hr四面,定级p6,面试经验分享总结!(含必考题答案)(代码片段)

...。背景描述首先描述下背景,楼主是一个3年多经验的Android开发工程师,先后服务于2家互联网公司,均从事于Android开发的工作。离职前我在最后这家公司已经工作了将 查看详情

自己总结的前端知识点(vue部分)(代码片段)

1.MVVM model-view-viewModel,model是数据与业务逻辑,view是UI界面,viewModel是一个对象用于实现model与view的同步。 ViewModel通过双向数据绑定把View层和Model层连接了起来。2.双向数据绑定vue.js是采用数据劫持结合发布者-订阅者模式的方式... 查看详情

android自定义view系列笔记收录

...w之后写的笔记和看过的文章收录一下,把自己学到的知识点总结一下。PS:下面把学习过并在文章里面有讲解的知识点打✔,不了解和文章里没有讲解的知识点打✘,以后会继续学习了解这些打✘的知识点,并查缺... 查看详情

一起talkandroid吧(第五百回:自定义view总结与忠告)(代码片段)

文章目录知识回顾经验总结各位看官们大家好,上一回中咱们说的例子是"自定义View实例五:简约工具栏",这一回中咱们说的例子是"自定义View的总结与忠告"。闲话休提,言归正转,让我们一起TalkAndroid吧!知识回顾看官们,关于... 查看详情

effectivejava在工作中的应用总结(代码片段)

...得每位Java开发者阅读。笔者将书中和平日工作较密切的知识点做了部分总结。作者|宜秋来源|阿里技术公众号《EffectiveJava》是一本经典的Java学习宝典,值得每位Java开发者阅读。笔者将书中和平日工作较密切的知识点做了部... 查看详情

nlpone-hot与tf-idf原理+面试必考知识点

查看详情

2021年10月大厂高频核心前端面试题总结,五万多字,面试必考

文章目录​​ 查看详情

java集合排序(面试必考点之一)

集合是Java面试必考知识点,而集合的排序也是非常重要的,工作中经常用到,那么这个知识点也是必须要掌握的,下面是我曾经面试时被面试官问的问题:根据API可知,Java集合的工具类Collections提供了两种排序方式:Collections.so... 查看详情

vue知识点总结

MVVM和MVC:什么是mvvm和mvcmvvm:modelviewview-model    mvvm是一种设计思想。Model层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View代表UI组件,它负责将数据模型转化成UI展现出来,ViewModel是一个同步V... 查看详情

androidview相关知识梳理和总结(代码片段)

一、自定义View相关问题1.自定义View的绘制流程?第一步:复写onMeasure方法。先measureChild方法测量出所有子控件的moMeasure。//1,测量自身super.onMeasure(widthMeasureSpec,heightMeasureSpec);//2,为每个子view计算测量的限制信息intwidthMode=MeasureSpec.... 查看详情

android中view的相关知识(代码片段)

Android中View的相关知识(6)@(Android)在前文Android中View的相关知识(4)和Android中View的相关知识(5)中,我们分析了在Activity中setContentView();和initWindowDecorActionBar();方法,即 查看详情

网络工程师考试知识点[必考知识点]--必看(代码片段)

网络工程师考试知识点1、常用的虚拟存储器由主存-辅存两级存储器组成2、中断向量可提供中断程序的入口地址3、DMA工作方式下,在主存与外设之间建立直接的数据通信。4、PERT不能清晰秒速各个任务之间的并行情况,... 查看详情