*转载请注明出处!*
一、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)
- 一个辅助动画实现的接口;
- 设置属性值 从“初始值” 【过渡】到“结束值”的变化规律(如:匀速、加速、减速、先加速后减速、先减速后加速。可根据需要的变化规律进行自定义插值器);
- 系统内置插值器:
- 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树。
本文暂时没有评论,来添加一个吧(●'◡'●)