Android开发之播放器中涉及的Surface,SurfaceView,SurfaceHolder基础

delphi外挂制作 KeyLife富翁笔记 (此作品参加“Borland ALM 产品开发者竞赛参赛”,请大家给他打分。) 作者: 微程标题: Delphi深度之旅——网络游戏外挂制作 关键字: 外挂,API,Delphi,游戏 分类: 开发经验 密级: 参赛 (评分:★★★★★ , 回复: 37, 阅读: 8595) »»昆明 刘悦 在几年前我看到别人玩网络游戏用上了外挂,做为程序员的我心里实在是不爽,想搞 阅读详情

一、什么是Surface

 

           简单的说Surface对应了一块屏幕缓冲区,每个window对应一个Surface,任何View都要画在Surface的Canvas上(后面有原因解释)。传统的view共享一块屏幕缓冲区,所有的绘制必须在UI线程中进行。

 

        在SDK的文档中,对Surface的描述是这样的:“Handle onto a raw buffer that is being managed by the screen compositor”,翻译成中文就是“由屏幕显示内容合成器(screen compositor)所管理的原始缓冲区的句柄”,这句话包括下面两个意思:

 

        1、通过Surface(因为Surface是句柄)就可以获得原生缓冲器以及其中的内容。就像在C++语言中,可以通过一个文件的句柄,就可以获得文件的内容一样。

 

        2、 原始缓冲区(a raw buffer)是用于保存当前窗口的像素数据的。

 

        引伸地,可以认为Android中的Surface就是一个用来画图形(graphics)或图像(image)的地方。

 

        根据Java方面的常规知识,我们知道通常画图是在一个Canvas对象上面进行的,由此,可以推知一个Surface对象中应该包含有一个Canvas(画布)对象。因此,在前面提及的两个意思的基础上,可以再加上一条:

 

        3、Surface中有一个Canvas成员,专门用于画图的。

 

        由以上的概括,我们总结如下:Surface中的Canvas成员,是专门用于供程序员画图的场所,就像黑板一样;其中的原始缓冲区是用来保存数据的地方;Surface本身的作用类似一个句柄,得到了这个句柄就可以得到其中的Canvas、原始缓冲区以及其它方面的内容。

 

      Surface是用来管理数据的。(句柄)

 

二、什么是SurfaceView

 

         说SurfaceView是一个View也许不够严谨,然而从定义中pubilc classSurfaceView extends View{.....}显示SurfaceView确实是派生自View,但是SurfaceView却有自己的Surface,请看SurfaceView的源码:

 

 

 

[java]  view plain copy
  1.  if (mWindow == null) {    
  2.          mWindow = new MyWindow(this);    
  3.          mLayout.type = mWindowType;    
  4.          mLayout.gravity = Gravity.LEFT|Gravity.TOP;    
  5.          mSession.addWithoutInputChannel(mWindow, mWindow.mSeq, mLayout,    
  6.          mVisible ? VISIBLE : GONE, mContentInsets);     
  7.    }   

 

        很明显,每个SurfaceView创建的时候都会创建一个MyWindow,new MyWindow(this)中的this正是SurfaceView自身,因此将SurfaceView和window绑定在一起,由第一部分我们知道,一个window对应一个Surface,因此SurfaceView也就内嵌了一个自己的Surface,可以认为SurfaceView是用来控制Surface中View的位置和尺寸的。

 

 

 

         SurfaceView就是展示Surface中数据的地方,同时可以认为SurfaceView是用来控制Surface中View的位置和尺寸的。

 

        大家都知道,传统View及其派生类的更新只能在UI线程,然而UI线程还同时处理其他交互逻辑,这就无法保证View更新的速度和帧率了,而SurfaceView可以用独立的线程进行绘制,因此可以提供更高的帧率,例如游戏,摄像头取景等场景就比较适合SurfaceView来实现。

 

 

 

三、什么是SurfaceHolder

 

        SurfaceHolder是一个接口,其作用就像一个关于Surface的监听器,提供访问和控制SurfaceView内嵌的Surface 相关的方法。它通过三个回调方法,让我们可以感知到Surface的创建、销毁或者改变。

 

        在SurfaceView中有一个方法getHolder,可以很方便地获得SurfaceView内嵌的Surface所对应的监听器接口SurfaceHolder。

 

        除下面将要提到的SurfaceHolder.Callback外,SurfaceHolder还提供了很多重要的方法,其中最重要的就是:

 

       1、abstract void addCallback(SurfaceHolder.Callbackcallback):为SurfaceHolder添加一个SurfaceHolder.Callback回调接口。

 

       2、abstract Canvas lockCanvas():获取一个Canvas对象,并锁定之。所得到的Canvas对象,其实就是Surface中一个成员。

 

       3、abstract Canvas lockCanvas(Rect  dirty):同上。但只锁定dirty所指定的矩形区域,因此效率更高。

 

       4、abstract void unlockCanvasAndPost(Canvas  canvas):当修改Surface中的数据完成后,释放同步锁,并提交改变,然后将新的数据进行展示,同时Surface中相关数据会被丢失。

 

        2、3、4中的同步锁机制的目的,就是为了在绘制的过程中,Surface中的数据不会被改变。lockCanvas是为了防止同一时刻多个线程对同一canvas写入。

 

总结:从设计模式的高度来看,Surface、SurfaceView和SurfaceHolder实质上就是广为人知的MVC,即Model-View-Controller。Model就是模型的意思,或者说是数据模型,或者更简单地说就是数据,也就是这里的Surface;View即视图,代表用户交互界面,也就是这里的SurfaceView;SurfaceHolder很明显可以理解为MVC中的Controller(控制器)。

 

四、什么是SurfaceHolder.Callback

 

        SurfaceHolder.Callback主要是当底层的Surface被创建、销毁或者改变时提供回调通知,由于绘制必须在Surface被创建后才能进行,因此SurfaceHolder.Callback中的surfaceCreated 和surfaceDestroyed 就成了绘图处理代码的边界。

 

        SurfaceHolder.Callback中定义了三个接口方法:

 

        1、abstract void surfaceChanged(SurfaceHolder holder, int format, int width, int height):当surface发生任何结构性的变化时(格式或者大小),该方法就会被立即调用。

 

        2、abstract void surfaceCreated(SurfaceHolder holder):当surface对象创建后,该方法就会被立即调用。

 

        3、abstract void  surfaceDestroyed(SurfaceHolder holder):当surface对象在将要销毁前,该方法会被立即调用。

 

 

 

五、实例演示

 

        下面,我们通过一个非常简单例子来实际感受一下,请留意代码中的注释:

 

        1、在Eclipse中创建一个Android Project项目TestSurfaceView,并选择生成缺省的Activity TestSurfaceViewActivity

 

        2、创建一个绘制线程如下:

 

 

 

[java]  view plain copy
  1. import android.graphics.Canvas;  
  2. import android.graphics.Color;  
  3. import android.graphics.Paint;  
  4. import android.graphics.Rect;  
  5. importandroid.view.SurfaceHolder;  
  6.   
  7. // 绘制线程  
  8. public class MyThread extends Thread  
  9. {  
  10.          private SurfaceHolder holder;  
  11.          private boolean run;  
  12.           
  13.          public  MyThread(SurfaceHolder holder)  
  14.          {  
  15.                    this.holder = holder;  
  16.                    run = true;  
  17.          }  
  18.   
  19.          @Override  
  20.          public void run()  
  21.          {  
  22.                    int counter = 0;  
  23.                    Canvas canvas = null;  
  24.                    while(run)  
  25.                    {  
  26.                             // 具体绘制工作  
  27.                             try  
  28.                             {  
  29.                                      // 获取Canvas对象,并锁定之  
  30.                                      canvas= holder.lockCanvas();  
  31.                                       
  32.                                      // 设定Canvas对象的背景颜色  
  33.                                      canvas.drawColor(Color.WHITE);  
  34.                                       
  35.                                      // 创建画笔  
  36.                                      Paint p = new Paint();  
  37.                                      // 设置画笔颜色  
  38.                                      p.setColor(Color.BLACK);  
  39.                                      // 设置文字大小  
  40.                                      p.setTextSize(30);  
  41.                                       
  42.                                      // 创建一个Rect对象rect  
  43.                                      Rect  rect = new Rect(100, 50, 380, 330);  
  44.                                      // 在canvas上绘制rect  
  45.                                      canvas.drawRect(rect,p);  
  46.                                      // 在canvas上显示时间  
  47.                                      canvas.drawText("Interval = " + (counter++) + " seconds.", 100, 410, p);  
  48.                                      Thread.sleep(1000);  
  49.                             }  
  50.                             catch(Exception e)  
  51.                             {  
  52.                                      e.printStackTrace();  
  53.                             }  
  54.                             finally  
  55.                             {  
  56.                                      if(canvas != null)  
  57.                                      {  
  58.                                                // 解除锁定,并提交修改内容  
  59.                                                holder.unlockCanvasAndPost(canvas);  
  60.                                      }  
  61.                             }  
  62.                    }  
  63.          }  
  64.   
  65.          public boolean isRun()  
  66.          {  
  67.                    return run;  
  68.          }  
  69.           
  70.          public void setRun(boolean run)  
  71.          {  
  72.                    this.run = run;  
  73.          }  
  74. }  

 

 

 

       3、自定义一个SurfaceView类如下:

 

 

 

[java]  view plain copy
  1. import android.content.Context;  
  2. import android.view.SurfaceHolder;  
  3. import android.view.SurfaceView;  
  4.   
  5. public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback  
  6. {  
  7.          private SurfaceHolder holder;  
  8.          private MyThread myThread;  
  9.           
  10.          public  MySurfaceView(Context context)  
  11.          {  
  12.                    super(context);  
  13.                     
  14.                    // 通过SurfaceView获得SurfaceHolder对象  
  15.                    holder = getHolder();  
  16.                     
  17.                    // 为holder添加回调结构SurfaceHolder.Callback  
  18.                    holder.addCallback(this);  
  19.                     
  20.                    // 创建一个绘制线程,将holder对象作为参数传入,这样在绘制线程中就可以获得holder  
  21.                    // 对象,进而在绘制线程中可以通过holder对象获得Canvas对象,并在Canvas上进行绘制  
  22.                    myThread = new MyThread(holder);  
  23.          }  
  24.   
  25.          // 实现SurfaceHolder.Callback接口中的三个方法,都是在主线程中调用,而不是在绘制线程中调用的  
  26.          @Override  
  27.          public void  surfaceChanged(SurfaceHolder holder, int format, int width, int height)  
  28.          {  
  29.          }  
  30.   
  31.          @Override  
  32.          public void  surfaceCreated(SurfaceHolder holder)  
  33.          {  
  34.                    // 启动线程。当这个方法调用时,说明Surface已经有效了  
  35.                    myThread.setRun(true);  
  36.                    myThread.start();  
  37.          }  
  38.   
  39.          @Override  
  40.          public void surfaceDestroyed(SurfaceHolder holder)  
  41.          {  
  42.                    // 结束线程。当这个方法调用时,说明Surface即将要被销毁了  
  43.                    myThread.setRun(false);  
  44.          }  
  45. }  

 


        4、修改TestSurfaceViewActivity.java代码,使之如下:

 

 

 

 

 

[java]  view plain copy
  1. import android.app.Activity;  
  2. import android.os.Bundle;  
  3.   
  4. public class TestSurfaceViewActivity extends Activity  
  5. {  
  6.     @Override  
  7.     public void onCreate(Bundle savedInstanceState)  
  8.     {  
  9.         super.onCreate(savedInstanceState);  
  10.         //setContentView(R.layout.main);  
  11.         setContentView(new MySurfaceView(this));  
  12.     }  
  13. }  

 


运行结果:

 

android view,surfaceview,glsurfaceview的区别:

答:SurfaceView是从View基类中派生出来的显示类,直接子类有GLSurfaceView和VideoView,可以看出GL和视频播放以及Camera摄像头一般均使用SurfaceView
SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。 
那么在UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。 
当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步。比如你触屏了一下,你需要surfaceView中thread处理,一般就需要有一个event queue的设计来保存touch event,这会稍稍复杂一点,因为涉及到线程同步。 

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

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

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

DELPHI XE2安装与配置全指南 DELPHI XE2作为Embarcadero公司推出的经典RAD开发工具,至今仍是许多传统行业软件维护和快速开发的首选环境。其安装过程涉及较多历史遗留组件和特殊配置,尤其在Windows 10/11新系统上会遇到不少兼容性问题。本文将从环境准备、安装介质验证、组件选择与定制安装、安装后关键配置等方面,详细解析DELPHI XE2的安装流程,并提供常见问题排查指南和性能优化技巧。对于需要进行数据库开发或集成第三方组件的开发者,本文还提供了针对性的配置建议和解决方案。 阅读详情

相关推荐

使用DELPHI 制做外挂

KeyLife富翁笔记 (此作品参加“Borland ALM 产品开发者竞赛参赛”,请大家给他打分。)  作者: 微程标题: Delphi深度之旅——网络游戏外挂制作 关键字: 外挂,API,Delphi,游戏 分类: 开发经验 密级: 参赛 (评分:★★★★★ , 回复: 37, 阅读: 8595) ?? 昆明 刘悦 在几年前我看到别人玩网络游戏用上了外挂,做为程序员的我心里实在是不爽,

wangyong495279的专栏 1065

Android中的Surface和SurfaceView

一、什么是Surface              简单的说Surface对应了一块屏幕缓冲区,每个window对应一个Surface,任何View都要画在Surface的Canvas上(后面有原因解释)。传统的view共享一块屏幕缓冲区,所有的绘制必须在UI线程中进行。           在SDK的文档中,对Surface的描述是这样的:“Handle onto a r

rong_wz的专栏 1143

Delphi HTTPS开发:解决Could not load SSL library错误与OpenSSL配置指南

在客户端网络编程中,SSL/TLS加密协议是保障数据传输安全的核心技术,其原理基于非对称加密与对称加密的结合,为HTTP通信提供身份验证与数据加密。HTTPS作为HTTP的安全版本,已成为现代Web服务与API交互的标配。在Delphi开发环境下,使用Indy组件库实现HTTPS客户端时,常因OpenSSL动态链接库配置问题导致连接失败。本文聚焦于TIdHTTP组件与TIdSSLIOHandlerSocketOpenSSL的集成,深入解析OpenSSL库的版本兼容性、DLL加载机制与部署策略,通过实操演示如

weixin_34023982的博客 418

Android图形系统之Surface与SurfaceHolder关系(四)

Surface 对象使应用能够渲染要在屏幕上显示的图像。通过 SurfaceHolder 接口,应用可以编辑和控制 Surface。 Surface Surface 是一个接口,供生产方与消耗方交换缓冲区。 用于显示 Surface 的 BufferQueue 通常配置为三重缓冲。缓冲区是按需分配的,因此,如果生产方足够缓慢地生成缓冲区(例如在 60 fps 的显示屏上以 30 fps 的速度进行缓冲),队列中可能只有两个分配的缓冲区。按需分配缓冲区有助于最大限度地减少内存消耗。您可以在 dumpsy.

Android系统攻城狮 3175

Delphi处理JSON别再手动拼接字符串了!用TJSONObject生成和解析的保姆级教程

本文详细介绍了Delphi中使用TJSONObject高效处理JSON数据的方法,告别手动拼接字符串的低效方式。通过实战示例和性能对比,展示了TJSONObject在类型安全、嵌套结构支持和错误检测等方面的优势,帮助开发者提升JSON处理效率和代码质量。

weixin_29913663的博客 343

4款主流EXE反编译工具对比:PE Explorer vs Resource Hacker vs eXeScope vs Passolo

本文深度对比了4款主流EXE反编译工具:PE Explorer、Resource Hacker、eXeScope和Passolo,从资源编辑到代码分析进行全面评测。通过功能矩阵和实战场景测试,帮助用户根据具体需求选择最适合的工具,提升软件逆向工程和本地化工作效率。

weixin_33937778的博客 392

AndroidStudio SurfaceView SurfaceHolder关系

电视机就像是屏幕,而 SurfaceView 则是你要在屏幕上显示的内容。然而,你不能直接在电视机上直接绘制内容,就像你不能直接在 SurfaceView 上绘制内容一样。这就是 SurfaceHolder 登场的地方。 SurfaceHolder 就像是遥控器,它是控制你如何在电视屏幕上显示内容的工具。你通过遥控器来切换频道、调整音量、改变画面设置等等,类似地,通过 SurfaceHolder...

zhaogaojian的专栏 192

Delphi XE开发HTTPS客户端,遇到‘Could not load SSL library‘别慌,手把手教你搞定OpenSSL库配置

本文详细介绍了在Delphi XE开发HTTPS客户端时遇到'Could not load SSL library'错误的解决方案。通过OpenSSL库的配置、DLL文件获取与部署、版本兼容性调优等步骤,帮助开发者快速解决SSL库加载问题,确保HTTPS通信的安全与稳定。

weixin_28730131的博客 335

Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的关系

转载请包含网址:http://blog.csdn.net/pathuang68/article/details/7351317 一、Surface Surface就是“表面”的意思。在SDK的文档中,对Surface的描述是这样的:“Handle onto a raw buffer that is being managed by the screen compositor”,翻译成中文就

玄机逸士的专栏 4万+

告别手动打码!实测Delphi调用PaddleOCR v4模型,识别带干扰线计算验证码的调参技巧

本文详细介绍了如何在Delphi环境中调用PaddleOCR v4模型高效识别带干扰线的计算式验证码。通过分析验证码预处理技术、PaddleOCR核心参数调优及实战案例,帮助开发者掌握OCR验证码识别的关键技巧,显著提升识别准确率至92%。

weixin_42525005的博客 186

AI论文写作工具评测与技术解析

自然语言处理(NLP)技术正在深刻改变学术写作方式,其核心是通过预训练模型实现文本生成与优化。基于Transformer架构的AI写作工具能自动完成文献检索、内容生成和语言润色等任务,显著提升科研效率。这类工具特别适合处理论文写作中的重复性工作,如SciSpace的文献管理和Paperpal的语法检查。在实际应用中,研究者需要平衡AI辅助与人工创作,遵守学术伦理规范,确保核心观点和实验数据的原创性。合理使用AI写作工具可以将传统论文写作时间缩短50%以上,让研究者更专注于创新性思考。

weixin_30471561的博客 435

[Android] Surface SurfaceView SurfaceHolder 三者之间的关系

Surface 是绘制对象,SurfaceView是一个组件,SurfaceHolder是SurfaceView操作Surface的接口。虽然SurfaceView里面包含Surface,但是SurfaceView无法直接操作Surface,需要借由SurfaceHolder这个接口类来操作。

ykun089的博客 538

互联网大厂测试流程实战:从需求评审到灰度上线的14个关键步骤详解

本文深入解析互联网大厂从需求评审到灰度上线的14个关键测试流程步骤,揭示如何通过流程化、工具化和规范化的手段实现高效质量保障。涵盖需求可测性评估、技术方案评审、测试用例设计、测试执行控制及持续改进机制,帮助团队提升测试效能与产品质量。

weixin_30632089的博客 519

surfaceView、surface和sufaceHolder的关系

初识Android中的surface相关

qq_35597336的博客 3223

《专家系统:从知识库到推理机的AI经典架构解析》

本文深入解析专家系统的经典架构,从知识库构建到推理机设计,揭示这一人工智能技术在医疗诊断、工业维护等领域的实用价值。通过实战案例展示专家系统与机器学习融合的三种层级,并分享性能优化、知识获取等关键开发经验,帮助开发者掌握这一AI经典技术的现代应用。

439

三维跨孔电磁波CT数据可视化框架搭建

利用matlab实现对跨孔电磁波CT实测数据反演,并搭建了三维CT数据可视化框架,可装填实测CT反演数据。

Neverlevsun的博客 1169

Android图形系统之Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的联系 && camera的takePicture实例

android中,与图形相关的上层java package包括:android.graphics,android.view,android.widget,android.opengl。 android.graphics,android.view和android.widget功能和其他类似的图形库如Qt/Gtk+差不多,分别提供基本的图形原语(如画点画线,设置图形上下文等),事件机制,以及开发图形

zhandoushi的专栏 1万+

SAP IDOC实战:如何用EDI实现跨公司采购订单自动生成销售订单(附完整配置步骤)

本文详细解析了如何利用SAP IDOC与EDI技术,实现跨公司采购订单自动生成销售订单的完整流程。通过实战案例,从业务蓝图设计、输出条件配置、伙伴参数设定到IDOC消息类型处理,提供了清晰的配置步骤与故障排查指南,帮助企业打通内部业务流,构建高效的自动化闭环。

weixin_29215815的博客 729

SurfaceView + SurfaceHolder 入门

最近准备研究cocos2d,所以先记录下SurfaceView学习笔记。

成长之路 1151

结构设计3D拆件与骨架模型构建实战:基于Creo 8.0的5个高效建模技巧

本文详细解析了基于Creo 8.0的结构设计3D拆件与骨架模型构建实战技巧,涵盖5个高效建模方法,包括参数化驱动、曲面分割、多实体协同设计等。通过骨架模型的智能应用,设计效率可提升30%以上,特别适合复杂产品的结构设计。文章还提供了TWS耳机充电仓等实战案例,帮助工程师快速掌握工业设计中的核心建模技术。

weixin_30000735的博客 573

Zephyr、FreeRTOS 和 RT-Thread

你是…更适合用嵌入式新手,刚接触 RTOSFreeRTOS(入门简单)IoT 项目开发,需要 BLE/WiFi/MQTTZephyr(协议全)想快速构建可部署的产品Zephyr(模块统一)只做单个任务或简单状态机控制FreeRTOS(轻量)做平台化、持续集成、自动测试Zephyr(CI 支持强)

is0815的博客 2246
上一篇: BitNami一键安装Redmine
下一篇: Android开发之MediaPlayer和SurfaceView播放视频
minimicall
博客等级 码龄18年 407粉丝 174原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值