Surfaceview和view的区别

View简介

View一般在onDraw方法里面绘图,onDraw在UI主线程执行。onDraw默认只在View初始化的时候调用一遍,所以View不会自动刷新画面,一般要调用invalidate或者postInvalidate来重新执行onDraw里面的代码进行刷新画面。UI主线程一般用来渲染组件、处理组件与用户之间的交互事件,比如说按钮的点击事件、文本框的输入事件。如果的画图任务相当繁重,那么onDraw方法里面的代码要执行好长一段时间,就可能会造成UI主线程阻塞。比如,如果在绘图的同时,用户刚好点击了某个按钮,那UI主线程会怎么处理点击事件呢?肯定是在绘图完毕后再处理点击事件,因为onDraw方法跟按钮点击事件处理都是在UI主线程内操作的。这样就给用户造成按钮点击延时处理的坏体验。

   



因为Android只允许在UI主线程内改变UI界面绘图完毕后渲染到屏幕的实质就是改变UI界面

SurfaceView简介

Surfaceview是视图(view)的一个继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个这个Surface的格式和尺寸,Surfaceview控制这个Surface的绘制位置。

Surfaceview也可以在onDraw里面绘图,即直接在UI主线程绘图并渲染,因为Surfaceview是View的子类。我们可以考虑这样的方案:在后台线程执行繁重的绘图任务,把所有绘制的东西缓存起来;绘制完毕后,再回到UI线程,一次性把所绘制的东西渲染到屏幕上(本质:就是后台线程绘制,UI主线程渲染

只使用View的onDraw方法是无法实现这种方案的,而Surfaceview可以实现这种方案。先看看Surfaceview的工作原理图:



SurfaceView的目的是提供给应用一个额外的Surface,但是这个Surface摆放在哪,大小多少就需要控制,SurfaceView就是拿来控制整个,它本身是没有内容的,或者说它就是在Activity的窗口上某个位置挖了一个某个大小的洞,让位于Activity窗口后面的Surface能被看到到。
因为Android限制了UI操作只能在主线程中。所以像游戏、视频播放这些绘制任务比较繁重,为了不堵塞主线程就需要用SurfaceView,它拥有自己的一个Surface,而因为是多线程的,只能让一个人在上面画,要是所有人都在同时画那岂不是乱套了,所以需要用lockCanvas来锁住,等画完再unlock。
SurfaceView是在什么时候创建?这个分两种情况,如果是在Xml布局文件里指定的那么就是随着Activity(这个可以想象成一个窗口页面)一起创建。或者在代码运行到一定时间再创建。而SurfaceView一开始创建出来后,它拥有的Surface不一定会一起创建出来,Surface有自己的生命周期,要等到SurfaceView可见时才正在创建,所以需要在Holder中设置一个Callback来让Surface状态变化时回调,这样我们就知道Surface当前状态是被创建了,还是已经被销毁了。被创建了表示可以开始准备绘制了,而被销毁后我们要释放其他资源。

surfaceView和View最本质的区别在于:

surfaceView是在一个新起的单独线程中可以重新绘制画面,而View必须在UI的主线程中更新画面。那么在UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。

所以基于以上,根据游戏特点,一般分成两类。

1 被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是依赖于 onTouch 来更新,可以直接使用 invalidate。 因为这种情况下,这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。

2 主动更新。比如一个人在一直跑动。这就需要一个单独的thread不停的重绘人的状态,避免阻塞main UI thread。所以显然view不合适,需要surfaceView来控制。



  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值