前端开发入门到精通的在线学习网站

网站首页 > 资源文章 正文

Android WMS 及 绘图机制(android canvas 绘图)

qiguaw 2024-09-03 17:41:21 资源文章 21 ℃ 0 评论

最新(2020)Android高级面试知识点干货分享(五)

*转载请注明出处!*

一、Android自定义View

更深入一点的,应该了解一下WMS,以及View与Window、Activity之间是怎么关联,怎么添加上去的。针对View,还得了解它的测量模式与测量规范。

  • 延伸:从源码角度分析View的绘制流程(onAttach--onMeasure---onLayout---onDraw)

$1.1、Activity、Window/PhoneWindow、View、ViewRootImpl、DecorView的关系

下面这图是我自己根据源码画的图:从Activity启动开始,WMS是如何把View添加到窗口上且与Activity相关起来的。


下面这图来源于网络,清楚的展现出了Activity、PhoneWindow/Window、DecorView三者之间的关系。



二、Android 动画绘制原理

$2.1、 Android屏幕刷新机制

  • 每隔16.6ms刷新一次屏幕(即每帧【每一屏幕】绘制时间大致为16.6ms:理想状态下,每秒展示不低于60帧(FPS)时才会感觉不到卡顿 ,即一帧屏幕绘制完耗时:1000ms/60fps = 16.6ms)
  • 帧的渲染过程(下图来源于google开发者文档)


$2.2、典型的显示系统:CPU、GPU、Buffer

(只有一个缓冲,又称单缓冲)


  • 显示器重要特性:
  • 行频(HSYNC:水平扫描频率Horizontal Scanning Frequency):HSYNC脉冲信号为高电平时,将告诉系统该扫描下一行了,即要转到下一行起始处了。
  • 场频(VSYNC:垂直扫描频率Vertical Scanning Frequency):由于屏幕是先从左至右扫描,再垂直扫描,因此场频也是作为屏幕刷新完毕的条件,即每秒屏幕刷新的的次数。
  • 行频 = 场频 * 纵坐标分辨率

(下图来源于网络)



  • VSync(VerticalSynchronization)垂直同步:

当屏幕从左至右,从上到下扫描一次完毕后,又将从头开始,进入下一次循环。

这时有一段时间空隙,叫做VBI(VerticalBlankingInterval)。

因为此时屏幕没有在刷新,这个时间点就是我们进行缓冲区交换的最佳时间,也就避免了交换过程中出现 screentearing的状况

VSync是属于脉冲信号,由高低电平来控制类似开关的操作。因此在VBI时,底层硬件发出VSync脉冲信号,来进行缓冲区数据的交互。


DoubleBuffer双缓冲系统:



Triple Buffer三级缓冲:

与双缓冲差不多,就是多了一个BackBuffer.

$2.3、 View动画(Tween Animation 补间动画)

  • - View.startAnimation(mAnimation):

调用此方法时,并不会立即开始动画,startAnimation方法里面会去遍历View树,调用draw()方法进行绘制,最终执行动画的方法是在draw()方法里面

  • 主要执行流程图:



记住一点:

View动画最后执行的原理为Matrix矩阵变换。比如:平移、缩放、旋转,Alpha渐变等。变换的是parentView,也就是ViewGroup,但对其他没影响。因此View动画才不会改变view的属性。

$2.4、 属性动画(Property Animator)

  • 工作原理

在一定时间间隔内,通过不断对值进行改变,并不断将该值赋给对象的属性,从而实现该对象在该属性上的动画效果

  • 执行流程图

属性动画在原理上与视图动画有很大的区别。属性动画是利用显示系统原理来进行渲染显示。在Android中主要是利用SurfaceFlinger 与 Choreographer来接收VSnc垂直同步信号,通过帧回调来刷新界面显示。

  • SurfaceFlinger:用于接收各种数据,并组进行组合,之后将结果存入FrameBuffer中。以便Display显示系统从中获取。类似【编剧】
  • Choreographer:编舞者。用于对View的编排。由ViewRootImpl持有。当接收到VSnc信号时,就会执行回调方法

插值器(Interpolator)

  1. 一个辅助动画实现的接口;
  2. 设置属性值 从“初始值” 【过渡】到“结束值”的变化规律(如:匀速、加速、减速、先加速后减速、先减速后加速。可根据需要的变化规律进行自定义插值器);
  3. 系统内置插值器:
  • LinearInterpolator(线性插值器):动画匀速改变
  • DecelerateInterpolator(减速插值器):动画高速开始,减速运行
  • AccelerateInterpolator(加速插值器):动画低速开始,加速运行
  • AccelerateDecelerateInterpolator:先加速后减速
  • AnticipateInterpolator:先退后,再加速向前至终点结束
  • AnticipateOvershootInterpolator:先退后,再加速先进,越过终点后,再返回终点
  • BounceInterpolator:到达终点后,再回弹,至静止
  • CycleInterpolator:周期运动(动画可以不到终点就回弹,也可以到了终点后在回弹,还可以回弹多次,小于1.0f不到终点就回弹,大于1.0f会到了终点后回弹,如果大于2,则会回弹多次)
  • OvershootInterpolator:快速完成动画,会超出一点然后再回到结束样式
  • PathInterpolator:根据路径来控制动画的执行快慢,路径可以是贝塞尔曲线,也可以是普通Path。

估值器(TypeEvaluator)

  • 一个辅助动画插值器实现的接口;
  • 设置属性值 在从初始值过渡到结束值的变化规律中的过渡值。(如:从0 过渡到1时,估值器会根据给定的插值器变化规律,估算出0~1之间的过渡值:0.4,0.6,0.7等)
  • 系统内置估值器:IntEvaluator、FloatEvaluator、ArgbEvaluator(针对Color)
  • 为属性动画所特有,可自定义

三、Android Camera系统

重点相关概念及知识点:

$3.1、照相机物理架构(下图来源于网络)


为生产者消费者模型

Camera负责生产,Display负责消费

名词解释:

  • IPU: Image Process Unit 图像处理单元,用于控制摄像机和显示屏
  • DMA:内存映射(在这里指将IPU采集到的数据DMA到内存里面
  • QBUF(QueueBuffer):缓存队列
  • DQBUF(DequeueBuffer):空闲队列

$3.2、Camera Android架构(下图来源于网络)


$3.3、Camera、Camera2、CameraX



$3.4、Surface、SurfaceView、SurfaceHolder

  • Surface: 对应一块屏幕缓冲区,它是由SurfaceFlinger(屏幕显示内容合成器)来管理的【原始缓冲区】的句柄(即Surface对象为SurfaceFlinger所持有)。

每个Window对应一个Surface。所有的View都要画在Surface的Canvas上。传统的View共享一块屏幕缓冲区,即共享一个Surface,且所有的绘制都在UI线程。


  • -总结:拿到Surface对象后,就可以获取原始缓冲区中的原始数据或者往缓冲区中存储数据、获取Canvas画布、其他。
  • SurfaceView:

它继承自View,里面新建了一个Window对象,因此SurfaceView内嵌了一个Surface,SurfaceView则用来控制Surface里面的View的位置与尺寸。


  • SurfaceHolder:

接口,用于访问和控制SurfaceView中Surface相关的方法。

Surface\SurfaceView\SurfaceHolder为典型的MVC模式。

$3. 5、SurfaceTexture

SurfaceTexture和SurfaceView不同的是,它对图像流的处理并不直接显示,而是转为GL外部纹理,因此可用于图像流数据的二次处理(如Camera滤镜,桌面特效等)。比如Camera的预览数据,变成纹理后有以下2种处理方式:

  • 可以交给GLSurfaceView直接显示,
  • 也可以通过SurfaceTexture交给TextureView作为View heirachy中的一个硬件加速层来显示。
  • 首先,SurfaceTexture从图像流(来自Camera预览,视频解码,GL绘制场景等)中获得帧数据,当调用updateTexImage()时,

根据内容流中最近的图像更新SurfaceTexture对应的GL纹理对象,

  • 接下来,就可以像操作普通GL纹理一样操作它了。
  • TextureView与SurfaceView的区别:
  • TextureView是将纹理加入到了View树中,因此可以像操作普通View一样操作此纹理控件。
  • SurfaceView则是有独立的Surface,可以在子线程中展示。独立于View树。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表