文档章节

Android之SurfaceView简单分析

 净琉璃
发布于 2017/04/25 13:09
字数 1792
阅读 2
收藏 0

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

 

 

本文转载自:http://www.cnblogs.com/xuling/archive/2011/06/06/android.html

共有 人打赏支持
粉丝 1
博文 89
码字总数 20910
作品 0
杭州
高级程序员
私信 提问
Android-SurfaceView与SurfaceHolder对象

1、Android-SurfaceView与SurfaceHolder对象: http://blog.csdn.net/andyhuabing/article/details/7657069 2、Android学习之 VideoView,SurfaceView: http://blog.csdn.net/abidepan/arti......

当空皓月
2014/12/18
0
0
Android:SurfaceView 的使用(附代码模板)

前言 摘自《Android群英传》 Android提供了View进行绘图处理,View可以满足大部分的绘图需求,但在某些时候也会心有余而力不足。我们知道,View通过刷新来重绘视图,Android 系统通过发出VSY...

涤生_Woo
2017/05/23
0
0
【Android游戏开发之六】在SurfaceView中添加组件!!!!并且相互交互数据!!!!

李华明Himi 原创,转载务必在明显处注明: 转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/android-game/306.html 很多童鞋说我的代码运行后,点击home或者back后会程序异常,...

迷途d书童
2012/03/19
0
0
Android音视频开发之SurfaceView的使用

由于公司业务要用到音视频方面的知识,所以我打算学习一下 Android 音视频开发。在网上搜索资料和教程,发现系统化的比较少,大多讲得比较零散。Jhuster 的博客 Android 音视频开发入门指南 ...

落英坠露
2018/10/28
0
0
【Android游戏开发十四】深入Animation,在SurfaceView中照样使用Android—Tween Animation!

李华明Himi 原创,转载务必在明显处注明: 转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/android-game/331.html 很多童鞋说我的代码运行后,点击home或者back后会程序异常,...

迷途d书童
2012/03/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

jenkins安装

https://my.oschina.net/u/593517/blog/1797968 jenkins 安装 https://my.oschina.net/u/593517/blog/3028175 GIT 安装 https://my.oschina.net/u/593517/blog/3028179 maven 安装 插件安装 ......

Gm_ning
11分钟前
1
0
小言服务端解决方案-监控

框架保证方向,整体包容细节 为保证服务端运行平稳正常,owner应使得系统应保有相应的监控:系统监控,业务监控。而服务运行的平稳高效是否有保障跟监控粒度又成直接的正比关系。本文仅针对开...

重城重楼
23分钟前
0
0
搜索引擎(Elasticsearch搜索详解)

学完本课题,你应达成如下目标: 掌握ES搜索API的规则、用法。 掌握各种查询用法 搜索API 搜索API 端点地址 GET /twitter/_search?q=user:kimchy GET /twitter/tweet,user/_search?q=user:...

这很耳东先生
46分钟前
6
0
浅谈如何减少GC的次数

GC会stop the world。会暂停程序的执行,带来延迟的代价。所以在开发中,我们不希望GC的次数过多。 本文将讨论如何在开发中改善各种细节,从而减少GC的次数。 (1)对象不用时最好显式置为 Nu...

浮躁的码农
48分钟前
1
0
jpa 自定义返回对象

任何ORM框架都少不了开放自定义sql的问题。jpa自然也不例外,很多场景需要写复杂sql的。 首先定义一个方法签名,然后打上@Query注解。像下面这样,需要注意nativeQuery,这个表示query中的字...

朝如青丝暮成雪
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部