SurfaceView、SurfaceHolder与Surface

article/2025/10/28 19:05:40

相关文章

  • SurfaceView、SurfaceHolder与Surface
  • TextureView、SurfaceTexture与Surface

按照官方文档的说法,SurfaceView继承自View,并提供了一个独立的绘图层,你可以完全控制这个绘图层,比如说设定它的大小,所以SurfaceView可以嵌入到View结构树中,但是需要注意的是,由于SurfaceView直接将绘图表层绘制到屏幕上,所以和普通的View不同的地方就在与它不能执行Transition,Rotation,Scale等转换,也不能进行Alpha透明度运算。SurfaceView的Surface排在Window的Surface(也就是View树所在的绘图层)的下面,SurfaceView嵌入到Window的View结构树中就好像在Window的Surface上强行打了个洞让自己显示到屏幕上,而且SurfaceView另起一个线程对自己的Surface进行刷新。特别需要注意的是SurfaceHolder.Callback的所有回调方法都是在主线程中回调的。

SurfaceView、SurfaceHolder、Surface的关系可以概括为以下几点:
* SurfaceView是拥有独立绘图层的特殊View
* Surface就是指SurfaceView所拥有的那个绘图层,其实它就是内存中的一段绘图缓冲区。
* SurfaceView中具有两个Surface,也就是我们所说的双缓冲机制
* SurfaceHolder顾名思义就是Surface的持有者,SurfaceView就是通过过SurfaceHolder来对Surface进行管理控制的。并且SurfaceView.getHolder方法可以获取SurfaceView相应的SurfaceHolder。
* Surface是在SurfaceView所在的Window可见的时候创建的。我们可以使用SurfaceHolder.addCallback方法来监听Surface的创建与销毁的事件。

下面我们写一个Demo来对普通的View与SurfaceView进行区别。

普通的View

我们先写一个继承自View的DrawView,我们每过1秒进行一次重绘

public class DrawView extends View {private static final int DELAY = 1000;private Paint mPaint;private int mCount;private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {mCount++;invalidate();handler.sendEmptyMessageDelayed(0x0001, DELAY);}};public DrawView(Context context) {this(context, null);}public DrawView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public DrawView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mPaint = new Paint();mPaint.setTextAlign(Paint.Align.CENTER);mPaint.setColor(0xFFFF0000);mPaint.setTextSize(50);}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();handler.sendEmptyMessageDelayed(0x0001, DELAY); //关联上Window后开始每1000ms重绘一次}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();handler.removeCallbacksAndMessages(null); //撤销关联时停止重绘,防止内存泄漏}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 在View的中间绘制一个HelloWorld 并写上重绘的次数canvas.drawText("Hello World" + mCount, getWidth() >> 1, getHeight() >> 1, mPaint);}
}

然后我们把DrawView放到View结构树中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextView
        android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:gravity="center"android:text="普通的View"android:textSize="20sp" /><cn.hufeifei.drawview.DrawView
        android:background="#ffffffff"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1" />
</LinearLayout>

为了能够看到DrawView刷新的情况,我们在开发者模式下打开显示surface更新的选项
打开显示surface更新的选项
执行结果
普通View重绘

由于这里是使用gif录制的结果图,我特意将gif帧率调节到33FPS,才有这样的效果图。
我们可以看到每隔1秒界面就刷新了一次,显然这里刷新的是Window的surface。
**(使用模拟器的同学需要注意了,由于模拟器在显示到PC屏幕的过程中有延迟,模拟器在绘制时可能使用了双缓冲,所以模拟器显示出来的可能界面刷新的频率不一样)
**

SurfaceView的重绘

这次我们的DrawSurfaceView继承自SurfaceView

public class DrawSurfaceView extends SurfaceView implements SurfaceHolder.Callback {private static final long DELAY = 1000;private final SurfaceHolder mHolder;private Paint mPaint;private int mCount;private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {mCount++;Canvas canvas = mHolder.lockCanvas();canvas.drawColor(0xFFFFFFFF);//擦除原来的内容canvas.drawText("Hello World" + mCount, getWidth() >> 1, getHeight() >> 1, mPaint);mHolder.unlockCanvasAndPost(canvas);sendEmptyMessageDelayed(0x0001, DELAY);}};public DrawSurfaceView(Context context) {this(context, null);}public DrawSurfaceView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public DrawSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mPaint = new Paint();mPaint.setTextAlign(Paint.Align.CENTER);mPaint.setColor(0xFFFF0000);mPaint.setTextSize(50);mHolder = getHolder();          //获取SurfaceView的ViewHolder对象mHolder.addCallback(this);    //为ViewHolder添加事件监听器}@Overridepublic void surfaceCreated(SurfaceHolder holder) {mHandler.sendEmptyMessageDelayed(0x0001, DELAY);Log.i("surfaceCreated", Thread.currentThread().getName());//打印当前线程的名字}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {Log.i("surfaceChanged", Thread.currentThread().getName());//打印当前线程的名字}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {mHandler.removeCallbacksAndMessages(null);Log.i("surfaceDestroyed", Thread.currentThread().getName());//打印当前线程的名字}
}

同样的我们把DrawSurfaceView放到View结构树中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextView
        android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:gravity="center"android:text="SurfaceView"android:textSize="20sp" /><cn.hufeifei.drawview.DrawSurfaceView
        android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1" />
</LinearLayout>

SurfaceView结果图

可以看到很明显的区别,SurfaceView并没有刷新Window,而只是刷新了SurfaceView所在的界面区域,可以看出SurfaceView使用的是自己的surface。
SurfaceHolder.Callback回调方法
从打印的log来看SurfaceHolder.Callback方法也确实是在主线程回调的。

实现代码点击这里


http://chatgpt.dhexx.cn/article/SRYTwrhK.shtml

相关文章

surfaceView、surface和sufaceHolder的关系

surfaceView、surface和sufaceHolder的关系 1.SurfaceView与Surface的联系2.SurfaceView3.Surface4.SurfaceHolder 1.SurfaceView与Surface的联系 简单来说&#xff0c;Surface是管理显示内容的数据&#xff08;implementsParcelable&#xff09;&#xff0c;包括存储于数据的…

线程天敌TerminateThread与SuspendThread http://blog.csdn.net/magictong/article/details/6304439

线程天敌TerminateThread与SuspendThread 标签&#xff1a; thread null delete dll c user 2011-04-06 13:22 10295人阅读 评论(1) 收藏 举报 分类&#xff1a; C Win32&#xff08;93&#xff09; 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得…

511遇见易语言API模块线程挂起(SuspendThread)

线程挂起用到的API是SuspendThread 511遇见易语言模块API教程 API 暂停指定的线程 函数功能&#xff1a; 挂起线程。 参数&#xff1a; 第1个参数&#xff1a; HANDLE hThread 线程句柄。 返回值&#xff1a; 成功&#xff1a;线程的前一个挂起数。 失败&#xff1a;-1。 …

面向对象设计6大原则

概览 单一职责 1、单一职责 Single Responsibility Principle&#xff0c;简称是SRP。SRP的英文定义是&#xff1a; There should never be more than one reason for a class to change. 翻译过来的意思是&#xff1a; 应该有且仅有一个原因引起类的变更。 或许我们可以…

带你了解面向对象的设计原则

##一 摘要 今天晚上给大家介绍一下面向对象的设计原则,为什么要介绍这个呢,原因很简单,大家平时所接触的语言,无论是object-C,C,JavaScrpt,C#等都是属于面向对象语言,既然是面向对象设计语言,那么就有必要去了解一下面向对象的设计原则.那么面向对象的设计原则有哪些呢?今天来…

面向对象七大设计原则

面向对象设计的七大原则 前言 在软件开发中&#xff0c;为了提高软件系统的可维护性和可复用性&#xff0c;增加软件的可扩展性和灵活性&#xff0c;我们能要尽量根据 7 条原则来开发程序&#xff0c;从而提高软件开发效率、节约软件开发成本和维护成本。 面向对象设计原则概…

软件设计与体系——面向对象设计的原则

一&#xff1a;前言 用一道题熟悉OO设计与编程&#xff1a;给定一个4位数&#xff08;数字不完全相同&#xff09;&#xff0c;这4个数字可以得到最大4位数和最小4位数&#xff0c;算它们的差&#xff0c;不是6174则重复上述过程&#xff0c;最终会得到6174&#xff0c;验证这…

面向对象设计七大原则

面向对象设计七大原则 1) 开-闭原则 &#xff08;Open Closed Principle&#xff0c;OCP&#xff09;定义开闭原则的作用实现方法例子其它例子代码 2) 里氏代换原则&#xff08;Liskov Substitutiion Principle&#xff0c;LSP&#xff09;定义作用实现方法例子 3) 依赖倒置原则…

面向对象设计六大原则

6大原则如下&#xff1a; 1)单一职责原则,一个合理的类&#xff0c;应该仅有一个引起它变化的原因&#xff0c;即单一职责,就是设计的这个类功能应该只有一个; 优点&#xff1a;消除耦合&#xff0c;减小因需求变化引起代码僵化。 2) 开-闭原则&#xff0c;讲的是设计要对扩展…

设计模式(三)——面向对象设计原则

设计模式需要遵循基本的软件设计原则。可维护性(Maintainability)和可复用性(Reusability)是衡量软件质量的重要的两个属性: 可维护性:软件能够被理解、改正、适应及扩展的难易程度可复用性:软件能够被复用的难易程度面向对象设计的原则是支持可维护性复用,一方面需要实…

程序员必备的七大面向对象设计原则(一)

花絮 每天都在和面向对象打交道&#xff0c;但是我们在应用面向对象的时候感觉自己的面向对象技术应用的很合理&#xff1f;理解的很到位&#xff1f;应用的很到位&#xff1f;用的时候恰到好处&#xff1f;用的是否符合软件的发展趋势&#xff1f; 上面很多一连串的问题&#…

面向对象设计原则之开闭原则

开闭原则是面向对象的可复用设计的第一块基石&#xff0c;它是最重要的面向对象设计原则。开闭原则由Bertrand Meyer于1988年提出&#xff0c;其定义如下&#xff1a; 开闭原则(Open-Closed Principle, OCP)&#xff1a;一个软件实体应当对扩展开放&#xff0c;对修改关闭。即…

面向对象设计模式5大基本原则

“宇宙万物之中,没有一样东西能像思想那么顽固。” 一爱默生 首先明确模式是针对面向对象的&#xff0c;它的三大特性&#xff0c;封装、继承、多态。 面向对象设计模式有5大基本原则&#xff1a;单一职责原则、开发封闭原则、依赖倒置原则、接口隔离原则、Liskov替换原…

面向对象六大设计原则

目录 1 、单一职责&#xff08;Single Responsibility Principle&#xff09; 2 、开闭原则&#xff08;Open Close Principle&#xff09; 3、里氏替换原则&#xff08;Liskov Substitution Principle&#xff09; 4、接口隔离原则&#xff08;Interface Segregation Prin…

阿里巴巴编码规范解读(六、七)-工程结构及设计规约

工程结构 应用分层 1.【推荐】 图中默认上层依赖于下层&#xff0c;箭头关系表示可直接依赖&#xff0c;如&#xff1a;开放接口层可以依赖于 Web层&#xff0c;也可以直接依赖于 Service层&#xff0c;依此类推。 开放接口层&#xff1a;可直接封装 Service 方法暴露成RPC…

面向对象设计的七大设计原则详解

面向对象的七大设计原则 文章目录 面向对象的七大设计原则简述七大原则之间的关系 一、开闭原则&#xff08;The Open-Closed Principle &#xff0c;OCP&#xff09;概念理解系统设计需要遵循开闭原则的原因开闭原则的实现方法一个符合开闭原则的设计开闭原则的相对性 二、 里…

Android Binder机制简述

一、Android binder是什么&#xff1f; Android平台上的一种跨进程通信&#xff08;IPC&#xff09;机制 从OpenBinder演化而来 从Android应用层角度来说&#xff0c;Binder是客户端和服务端进行通信的媒介 二、IPC原理 每个Android进程&#xff0c;只能运行在自己的进程所…

不得不说的Android Binder机制与AIDL

说起Android的进程间通信&#xff0c;想必大家都会不约而同的想起Android中的Binder机制。而提起Binder&#xff0c;想必也有不少同学会想起初学Android时被Binder和AIDL支配的恐惧感。但是作为一个Android开发者&#xff0c;Binder是我们必须掌握的知识。因为它是构架整个Andr…

FrameWork-进程间通信之Binder机制AIDL

进程间通信之Binder机制 Binder是什么&#xff1f;为什么要使用Binder&#xff1f;Binder原理Binder使用实战 1、Binder是什么 Binder 是一种进程间通信机制&#xff0c;基于开源的 OpenBinder 实现&#xff1b;OpenBinder 起初由 Be Inc. 开发&#xff0c;后由 Plam Inc. 接…