surfaceview详解

1.概念

      SurfaceView是View类的子类,可以直接从内存或者DMA等硬件接口取得图像数据,是个非常重要的绘图视图。它的特性是:可以在主线程之外的线程中向屏幕绘图上。这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。在游戏开发中多用到SurfaceView,游戏中的背景、人物、动画等等尽量在画布canvas中画出。

2.实现方法

1)实现步骤

    a.继承SurfaceView

    b.实现SurfaceHolder.Callback接口

2)需要重写的方法

[java] view plaincopy

  1. public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){}  //在surface的大小发生改变时激发  

[java] view plaincopy

  1. public void surfaceCreated(SurfaceHolder holder){}  //在创建时激发,一般在这里调用画图的线程。  

[java] view plaincopy

  1. public void surfaceDestroyed(SurfaceHolder holder) {}  //销毁时激发,一般在这里将画图的线程停止、释放。  

 

3)SurfaceHolder

  SurfaceHolder,surface的控制器,用来操纵surface。处理它的Canvas上画的效果和动画,控制表面,大小,像素等。
几个需要注意的方法:

[java] view plaincopy

  1. abstract void addCallback(SurfaceHolder.Callback callback);  
  2. // 给SurfaceView当前的持有者一个回调对象。  
  3. abstract Canvas lockCanvas();  
  4. // 锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。  
  5. abstract Canvas lockCanvas(Rect dirty);  
  6. // 锁定画布的某个区域进行画图等..因为画完图后,会调用下面的unlockCanvasAndPost来改变显示内容。  
  7. // 相对部分内存要求比较高的游戏来说,可以不用重画dirty外的其它区域的像素,可以提高速度。  
  8. abstract void unlockCanvasAndPost(Canvas canvas);  
  9. // 结束锁定画图,并提交改变。  

4)总结整个过程

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

下面是一个完整的案例:

[java] view plaincopy

  1. public class ViewTest extends Activity {    @Override  
  2.       public void onCreate(Bundle savedInstanceState) {  
  3.          super.onCreate(savedInstanceState);  
  4.          setContentView(new MyView(this));  
  5.       }     //视图内部类  
  6.       class MyView extends SurfaceView implements SurfaceHolder.Callback  
  7.       {  
  8.          private SurfaceHolder holder;  
  9.          private MyThread myThread;   
  10.          public MyView(Context context) {  
  11.              super(context);  
  12.              // TODO Auto-generated constructor stub  
  13.              holder = this.getHolder();  
  14.              holder.addCallback(this);  
  15.              myThread = new MyThread(holder);//创建一个绘图线程  
  16.          }  
  17.     
  18.          @Override  
  19.          public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  20.                   int height) {  
  21.              // TODO Auto-generated method stub  
  22.                  
  23.          }  
  24.     
  25.          @Override  
  26.          public void surfaceCreated(SurfaceHolder holder) {  
  27.               // TODO Auto-generated method stub  
  28.              myThread.isRun = true;  
  29.              myThread.start();  
  30.         }  
  31.     
  32.         @Override  
  33.          public void surfaceDestroyed(SurfaceHolder holder) {  
  34.             // TODO Auto-generated method stub  
  35.             myThread.isRun = false;  
  36.         }  
  37.       }  
  38.       //线程内部类  
  39.       class MyThread extends Thread  
  40.       {  
  41.           private SurfaceHolder holder;  
  42.           public boolean isRun ;  
  43.           public  MyThread(SurfaceHolder holder)  
  44.           {  
  45.               this.holder =holder;   
  46.               isRun = true;  
  47.           }  
  48.           @Override  
  49.           public void run()  
  50.           {  
  51.               int count = 0;  
  52.               while(isRun)  
  53.               {  
  54.                   Canvas c = null;  
  55.                   try  
  56.                   {  
  57.                       synchronized (holder){  
  58.                         c = holder.lockCanvas();//锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。  
  59.                     c.drawColor(Color.BLACK);//设置画布背景颜色  
  60.                     Paint p = new Paint(); //创建画笔  
  61.                     p.setColor(Color.WHITE);  
  62.                     Rect r = new Rect(100, 50, 300, 250);  
  63.                     c.drawRect(r, p);  
  64.                     c.drawText("这是第"+(count++)+"秒", 100, 310, p);  
  65.                     Thread.sleep(1000);//睡眠时间为1秒  
  66.                   }  
  67.               }  
  68.               catch (Exception e) {  
  69.                   e.printStackTrace();  
  70.               }  
  71.               finally  
  72.               {  
  73.                    if(c!= null)  
  74.                  {  
  75.                    holder.unlockCanvasAndPost(c);//结束锁定画图,并提交改变。  
  76.                 }  
  77.            }  
  78.          }  
  79.        }  
  80.      }  
  81.   } 
时间: 2024-09-14 21:19:57

surfaceview详解的相关文章

基于 SurfaceView 详解 android 幸运大转盘,附带实例app

基于 SurfaceView 详解 android 幸运大转盘,附带实例app       首先说一下,幸运大转盘,以及SurfaceView是在看了也为大神的博客,才有了比较深刻的理解,当然这里附上这位大神的博客地址:博客地址,有兴趣的话你可以去看看,里面有很多的例子.至于我为什么要写这篇博客?,原因之一:加强自己的理解,原因之二:大神的博客就是大神的博客,跳转的太快,基础不好的,很难理解.还有就是一天在实验室太无聊了,没事写写东西.这里我再来更加基础的分析一下.写的不好,原谅.有什么写的不对

Android 自定义SurfaceView详解

本文简单讨论以后Android游戏引擎模板的架构问题.在Android游戏开发教程之二:View类与SurfaceView类中我们已经谈到,SurfaceView类是有很多优势的,所以在Android游戏开发中还是选择SurfaceView. 这里我们直接继承SurfaceView,实现SurfaceHolder.Callback接口,处理surfaceCreated.surfaceChanged以及surfaceDestroyed方法,这里我们并没有把按键控制传入,最终游戏的控制方面仍然由Vi

Android编程之SurfaceView实例详解_Android

本文实例讲述了Android编程之SurfaceView用法.分享给大家供大家参考,具体如下: 关于surfaceView相关知识: View和SurfaceView主要区别: 1. View只能在UI线程中刷新,而SurfaceView可以在子线程中刷新 2. SurfaceView可以控制刷新频率 SurfaceView几个重要的方法: 1. 继承SurfaceView 后调用getHolder()方法可以获取到mSurfaceHolder对象这个对于可以控制SurfaceView的绘制 2

Android仿微信清理内存图表动画(解决surfaceView屏幕闪烁问题)demo实例详解_Android

最近接了一个项目其中有功能要实现一个清理内存,要求和微信的效果一样.于是想到用surfaceView而不是继承view.下面小编给大家解析下实现思路. surfaceView是为了解决频繁绘制动画产生了闪烁,而采用了双缓冲机制,即A.B两个缓冲轮流显示在画布上,同时,使用不当,同样容易产生闪烁,这是由于A.B中有一个缓冲没有改变. 在我写这个view的时候就遇到了这个问题,研究了好久终于解决. 首先说一下思路: 微信清理缓存的动画是: 一个圆环不停的转动,同时中间有文字显示-->加载完成后,出现

【ANDROID游戏开发十三】(保存游戏数据 [下文])详解SQLITE存储方式,并把SQLITE的数据库文件存储在SD卡中!!!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/329.html ----------------------- 『很多童鞋说我的代码运行后,点击home或者back后会程序异常,如果你也这样遇到过,那么你肯定没有仔细读完Himi的博文,第十九篇Himi专门写了关于这些错误的原因和解决方法,这里我在博客都补充说明下,省的童鞋们总疑惑这一块:请点击下面联系进入阅读:

【ANDROID游戏开发之八】游戏中添加音频-详解MEDIAPLAYER与SOUNDPOO!并讲解两者的区别和游戏中的用途!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/312.html  ----------------------- 『很多童鞋说我的代码运行后,点击home或者back后会程序异常,如果你也这样遇到过,那么你肯定没有仔细读完Himi的博文,第十九篇Himi专门写了关于这些错误的原因和解决方法,这里我在博客都补充说明下,省的童鞋们总疑惑这一块:请点击下面联系进入阅读

【ANDROID游戏开发十二】(保存游戏数据 [上文])详解SHAREDPREFERENCE 与 FILEINPUTSTREAM/FILEOUTPUTSTREAM将数据存储到SD卡中!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/327.html ----------------------- 『很多童鞋说我的代码运行后,点击home或者back后会程序异常,如果你也这样遇到过,那么你肯定没有仔细读完Himi的博文,第十九篇Himi专门写了关于这些错误的原因和解决方法,这里我在博客都补充说明下,省的童鞋们总疑惑这一块:请点击下面联系进入阅读:

android如何自定义TextView详解

Android控件中的TextView控件只有一个输入框,但是为了用于的操作方便我们应该实现一些功能: 1. 可以直接将内容删除的功能按钮 2. 可以记录用户以前输入的数据,同时能够将数据通过下拉显示,点击的时候实现输入 先上图: 下拉的图片没有做,所以和删除的图片使用同一个了,同志们可以直接在xml文件中更换就行了 分析: 肯定要使用自定义view来实现的,我们知道自定义view大概可以分为三类:自绘控件,组合控件,继承控件,我们这里是要进行增强的textView的功能,所以我这里使用的 是组

Android编程实现手机拍照的方法详解_Android

本文实例讲述了Android编程实现手机拍照的方法.分享给大家供大家参考,具体如下: 今天弄了差不多一天手机拍照,后来,边弄边想,而且现在也不知道自己知道的这些对不对,首先,如果使用此种方式拍照的话,程序在模拟器中,刚启动就会出问题,不知道什么原因,猜可能是因为是模拟器的原因,目前没有手机进行测试,这一些无法解释,代码如下: Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(in