SurfaceView为什么不能做动画?

目录
      • Android屏幕绘制流程是什么?
      • SurfaceView为什么不能做动画?
      • TextureView也可以实现视频播放,为什么TextureView可以做动画?

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 详解

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/625898.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-16
下一篇 2022-04-16

发表评论

登录后才能评论

评论列表(0条)

保存