- Android屏幕绘制流程是什么?
- SurfaceView为什么不能做动画?
- TextureView也可以实现视频播放,为什么TextureView可以做动画?
从View.invalidate到view.draw的大致流程如下:
View.draw之后的流程涉及到系统服务SurfaceFlinger,下面是硬件加速的流程:
下面是软件加速的绘制流程:
SurfaceView直接继承自View,自己重写了View的draw方法,直接实现了和系统服务SurfaceFlinger的通信。
也就是上图中硬件加速和软件加速的绘制流程。
public class SurfaceView extends View {
static private final String TAG = "SurfaceView";
static private final boolean DEBUG = false;
...
@Override
public void draw(Canvas canvas) {
if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
// draw() is not called when SKIP_DRAW is set
if ((mPrivateFlags & SKIP_DRAW) == 0) {
// punch a whole in the view-hierarchy below us
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
}
}
super.draw(canvas);
}
...
}
并且绘制流程不是依赖ViewRootImpl的Surface,导致View的属性不受ViewRootImpl的绘制流程控制。
所以不能控制动画。
一般的Activity包含的多个View会组成View hierachy的树形结构,只有最顶层的DectorView才是对WMS可见的,这个DecorView在WMS中有一个对应的WindowState,在SurfaceFlinger中有对应的Layer。
而SurfaceView正因为它有自己的Surface,有自己的Window,它在WMS中有对应的WindowState,在SurfaceFlinger中有Layer。 虽然在App端它仍在View hierachy中,但在Server端(WMS和SurfaceFlinger)中,它与宿主窗口是分离的。 这个Surface不在View hierachy中,它的显示也不受View的属性控制,所以不能进行平移、缩放等动画。
其他博客上有讲,从 Android7.0 开始,SurfaceView 的窗口位置与其他 View 渲染同步更新。
这意味着在屏幕上平移和缩放 SurfaceView 不会导致渲染失真。
很早的版本不能做动画,现在的Android系统已经可以做动画了,还解决了View层的vsync问题。
精力有限,这个观点还没有考证。
TextureView是在View hierachy中做绘制,因此一般它是在主线程上做的(在Android 5.0引入渲染线程后,它是在渲染线程中做的。
主线程MainThread与渲染线程RenderThread
android的surfaceflinger原理学习
Android系统CPU与GPU工作流程
用MediaPlayer+TextureView封装一个完美实现全屏、小窗口的视频播放器
SurfaceView 与 TextureView 详解
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)