首先我们先来看下官方API对SurfaceView的介绍

SurfaceView的API介绍

Provides a dedicated drawing surface embedded inside of a view hierarchy. You can control the format of this surface and, if you like, its size; the SurfaceView takes care of placing the surface at the correct location on the screen

The surface is Z ordered so that it is behind the window holding its SurfaceView; the SurfaceView punches a hole in its window to allow its surface to be displayed. The view hierarchy will take care of correctly compositing with the Surface any siblings of the SurfaceView that would normally appear on top of it. This can be used to place overlays such as buttons on top of the Surface, though note however that it can have an impact on performance since a full alpha-blended composite will be performed each time the Surface changes.

Access to the underlying surface is provided via the SurfaceHolder interface, which can be retrieved by calling getHolder().

The Surface will be created for you while the SurfaceView's window is visible; you should implement surfaceCreated(SurfaceHolder) and surfaceDestroyed(SurfaceHolder) to discover when the Surface is created and destroyed as the window is shown and hidden.

One of the purposes of this class is to provide a surface in which a secondary thread can render in to the screen. If you are going to use it this way, you need to be aware of some threading semantics:

•All SurfaceView and SurfaceHolder.Callback methods will be called from the thread running the SurfaceView's window (typically the main thread of the application). They thus need to correctly synchronize with any state that is also touched by the drawing thread.
•You must ensure that the drawing thread only touches the underlying Surface while it is valid -- between SurfaceHolder.Callback.surfaceCreated() and SurfaceHolder.Callback.surfaceDestroyed().
对应的中文翻译
SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置。
        surface是纵深排序(Z-ordered)的,这表明它总在自己所在窗口的后面。surfaceview提供了一个可见区域,只有在这个可见区域内 的surface部分内容才可见,可见区域外的部分不可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者 surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,如果surface上面 有透明控件,那么它的每次变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。
        你可以通过SurfaceHolder接口访问这个surface,getHolder()方法可以得到这个接口。
        surfaceview变得可见时,surface被创建;surfaceview隐藏前,surface被销毁。这样能节省资源。如果你要查看 surface被创建和销毁的时机,可以重载surfaceCreated(SurfaceHolder)和 surfaceDestroyed(SurfaceHolder)。
        surfaceview的核心在于提供了两个线程:UI线程和渲染线程。这里应注意:
        1> 所有SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用,一般来说就是应用程序主线程。渲染线程所要访问的各种变量应该作同步处理。
        2> 由于surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之间有效,所以要确保渲染线程访问的是合法有效的surface。

接下来呢,说说自己对它的理解
1、定义

可以直接从内存或者DMA等硬件接口取得图像数据,是个非常重要的绘图容器。

它的特性是:可以在主线程之外的线程中向屏幕绘图上。这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。在游戏开发中多用到SurfaceView,游戏中的背景、人物、动画等等尽量在画布canvas中画出。

2、实现

首先继承SurfaceView并实现SurfaceHolder.Callback接口
使用接口的原因:因为使用SurfaceView 有一个原则,所有的绘图工作必须得在Surface 被创建之后才能开始(Surface—表面,这个概念在 图形编程中常常被提到。基本上我们可以把它当作显存的一个映射,写入到Surface 的内容
                      可以被直接复制到显存从而显示出来,这使得显示速度会非常快),而在Surface 被销毁之前必须结束。所以Callback 中的surfaceCreated 和surfaceDestroyed 就成了绘图处理代码的边界。

需要重写的方法

 (1)public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){}

     //在surface的大小发生改变时激发

 (2)public void surfaceCreated(SurfaceHolder holder){}

     //在创建时激发,一般在这里调用画图的线程。

 (3)public void surfaceDestroyed(SurfaceHolder holder) {}

     //销毁时激发,一般在这里将画图的线程停止、释放。

整个过程:继承SurfaceView并实现SurfaceHolder.Callback接口 ----> SurfaceView.getHolder()获得SurfaceHolder对象 ---->SurfaceHolder.addCallback(callback)添加回调函数---->SurfaceHolder.lockCanvas()获得Canvas对象并锁定画布----> Canvas绘画 ---->SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。

3、SurfaceHolder
这里用到了一个类SurfaceHolder,可以把它当成surface的控制器,用来操纵surface。处理它的Canvas上画的效果和动画,控制表面,大小,像素等。
几个需要注意的方法:
(1)、abstract void addCallback(SurfaceHolder.Callback callback);
// 给SurfaceView当前的持有者一个回调对象。
(2)、abstract Canvas lockCanvas();
// 锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。
(3)、abstract Canvas lockCanvas(Rect dirty);
// 锁定画布的某个区域进行画图等..因为画完图后,会调用下面的unlockCanvasAndPost来改变显示内容。
// 相对部分内存要求比较高的游戏来说,可以不用重画dirty外的其它区域的像素,可以提高速度。
(4)、abstract void unlockCanvasAndPost(Canvas canvas);
// 结束锁定画图,并提交改变。

4、实例

这里的例子实现了一个矩形和一个计时器

View Code package xl.test;import android.app.Activity;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.os.Bundle;import android.view.SurfaceHolder;import android.view.SurfaceView;public class ViewTest extends Activity {/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(new MyView(this));}//视图内部类class MyView extends SurfaceView implements SurfaceHolder.Callback{private SurfaceHolder holder;private MyThread myThread; public MyView(Context context) {super(context);// TODO Auto-generated constructor stubholder = this.getHolder();holder.addCallback(this);myThread = new MyThread(holder);//创建一个绘图线程}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {// TODO Auto-generated method stub}@Overridepublic void surfaceCreated(SurfaceHolder holder) {// TODO Auto-generated method stubmyThread.isRun = true;myThread.start();}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stubmyThread.isRun = false;}}//线程内部类class MyThread extends Thread{private SurfaceHolder holder;public boolean isRun ;public  MyThread(SurfaceHolder holder){this.holder =holder; isRun = true;}@Overridepublic void run(){int count = 0;while(isRun){Canvas c = null;try{synchronized (holder){c = holder.lockCanvas();//锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。c.drawColor(Color.BLACK);//设置画布背景颜色Paint p = new Paint(); //创建画笔p.setColor(Color.WHITE);Rect r = new Rect(100, 50, 300, 250);c.drawRect(r, p);c.drawText("这是第"+(count++)+"秒", 100, 310, p);Thread.sleep(1000);//睡眠时间为1秒}}catch (Exception e) {// TODO: handle exceptione.printStackTrace();}finally{if(c!= null){holder.unlockCanvasAndPost(c);//结束锁定画图,并提交改变。}}}}}}

注意:在surfaceView的构造函数中需要首先通过getHolder获取surfaceHolder,然后必须调用addCallBack()方法,同时需要设置好画笔属性,界面获取焦点。在surfaceCreated()中需要获取屏幕宽高,同时初始化游戏所需的数据资源,创建画图线程同时启动。在画图线程中必须设置flag标识让其循环监测,在surfaceDestroyed()方法中设置flag为false终止画图线程。画图线程中需要调用画图函数myDraw()和游戏界面逻辑处理函数logic()。在myDraw中首先必须通过surfaceHolder锁定画板,针对不同的游戏状态然后调用其对应类的画图函数,myDraw结束必须解锁画板。

转载于:https://www.cnblogs.com/xiaoran1129/archive/2012/08/30/2663069.html

android 学习之SurfaceView相关推荐

  1. 播放视频android学习笔记---44_在线视频播放器,网络视频解析器,SurfaceView 控件使用方法...

    最近用使开辟的过程中涌现了一个小题问,顺便录记一下因原和法方--播放视频 44_在线视频播放器 ------------------------- 1.注意这里,在模拟器中,android2.2和an ...

  2. android学习笔记---44_在线视频播放器,网络视频解析器,SurfaceView 控件使用方法

    44_在线视频播放器 ------------------------- 1.注意这里,在模拟器中,android2.2和android2.1视频是没有播放效果的,这个主要是因为模拟器的原因和程序代码 ...

  3. Android学习路线

    Android学习路线 第一阶段:Java面向对象编程 1.Java基本数据类型与表达式,分支循环.  2.String和StringBuffer的使用.正则表达式.  3.面向对象的抽象,封装,继承 ...

  4. 《Android学习指南》目录

    转自:http://android.yaohuiji.com/about Android学习指南的内容分类: 分类 描述 0.学习Android必备的Java基础知识 没有Java基础的朋友,请不要先 ...

  5. Android:Android学习路线图

    https://blog.csdn.net/libing1991_/article/details/53455243 前言 工作快一年,Android完全靠自学,看着那些基础教程一步步去做,写过简单的 ...

  6. 2015最新Android学习线路图

    Android是一个以Linux为基础的半开源操作系统,主要用于移动设备,由Google和开放手持设备联盟开发与领导.据2011年初数据显示仅正式上市两年的操作系统Android已经跃居全球最受欢迎的 ...

  7. android学习笔记1

    adb 常用命令 adb device  adb kill-server adb start-server adb install adb uninstall adb pull  adb push  ...

  8. Android学习博客和文章存档

    [Android基础]Android总结篇 http://blog.csdn.net/codeemperor/article/details/51004189 Android最佳性能实践(一)--合理 ...

  9. Android学习笔记:Android基础知识点(不断更新中)

    1.Android学习笔记:OkHttp 2.Android学习笔记:更新UI的方法(UI线程和非UI线程) 3.Android学习笔记:Volley 4.Android学习笔记:Handler 5. ...

  10. Android 学习进阶之路

    Android 学习进阶之路 java 基础知识点 java 高阶知识点 数据结构及算法知识点 Android 基础知识点 Android 高级必备素质 Android 技术难点 java 基础知识点 ...

最新文章

  1. 结合ashx来在DataGrid中显示从数据库中读出的图片
  2. 山寨c 标准库中的getline 函数
  3. C语言基础(12)-输入和输出
  4. mysql near_完美解决 ERROR 1064 (42000): You have an error in your SQL syntax ... near …
  5. centOs7上用yum安装软件报错
  6. emulator: Trying to vcpu execute at eip:6d4053
  7. 并发编程-04线程安全性之原子性Atomic包的4种类型详解
  8. AI:2021年WAIC世界人工智能大会2021年7月9日《可信AI论坛》、《AI引领探索保险科技新价值》、《产研共育·数智未来》等论坛演讲内容分享及解读
  9. 图解python_图解Python深拷贝和浅拷贝
  10. python设置cookie_Python中cookie的设置方法
  11. es6 使用修饰器实现Mixin模式
  12. 未来十年,你的人生目标在哪里?
  13. 基于 Vue 的轻量级静态网站生成器 VuePress
  14. 小学生把自己学校的网站搞了!
  15. javascript 和 jsp (java server page)的区别
  16. python 异常类型
  17. 乐购系统源码可多开站
  18. sodp软件如何导入多个工作面信息_6款堪称业界良心的软件,好用到想为它们疯狂打call!...
  19. js调用html页面跳转,js实现页面跳转的方法
  20. SPSS中K均值聚类操作案例

热门文章

  1. python求解非递减排序的数组的一个旋转的最小元素
  2. oracle 会话状态,oracle 常用状态sql
  3. fisco bcos 区块链配置文件位置
  4. 区块链 xuperchain 命令行 部署使用EVM solidity合约 教程
  5. Hyperledger Composer和Hyperledger Fabric的关系、区别及概念
  6. 去除移动端alert/confirm的网址(url)
  7. c语言中mylist是什么参数,数据结构题集(C语言版)算法设计题解析-第二章
  8. 五连阳回调买入法_一旦出现“4连阳+1阴”形态,坚定满仓买入,百分百是主升浪...
  9. Unity Camera
  10. android 拍照 比例,Android全屏摄像头 – 同时保持摄像头选择的比例