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为什么不能做动画?的主要内容,如果未能解决你的问题,请参考以下文章

Android使用surfaceView原生绘制

安卓surfaceview动画

自定义 View 动画比自定义 SurfaceView 动画更流畅?

Android中使用SurfaceView和Canvas来绘制动画

2048游戏回顾一:使用SurfaceView创建游戏启动动画

surfaceview