SurfaceView为什么不能做动画?
Posted zhangjin1120
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SurfaceView为什么不能做动画?相关的知识,希望对你有一定的参考价值。
目录
android屏幕绘制流程是什么?
从View.invalidate到view.draw的大致流程如下:
View.draw之后的流程涉及到系统服务SurfaceFlinger,下面是硬件加速的流程:
下面是软件加速的绘制流程:
SurfaceView为什么不能做动画?
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也可以实现视频播放,为什么TextureView可以做动画?
TextureView是在View hierachy中做绘制,因此一般它是在主线程上做的(在Android 5.0引入渲染线程后,它是在渲染线程中做的。
主线程MainThread与渲染线程RenderThread
android的surfaceflinger原理学习
Android系统CPU与GPU工作流程
用MediaPlayer+TextureView封装一个完美实现全屏、小窗口的视频播放器
SurfaceView 与 TextureView 详解
以上是关于SurfaceView为什么不能做动画?的主要内容,如果未能解决你的问题,请参考以下文章
自定义 View 动画比自定义 SurfaceView 动画更流畅?
Android中使用SurfaceView和Canvas来绘制动画