Chinaunix首页 | 论坛 | 博客
  • 博客访问: 383752
  • 博文数量: 214
  • 博客积分: 770
  • 博客等级: 军士长
  • 技术积分: 1969
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-08 01:22
文章分类

全部博文(214)

文章存档

2013年(110)

2012年(104)

我的朋友

分类: Android平台

2013-08-05 12:10:27

        可以认为Android中的Surface就是一个用来画图形(graphics)或图像(image)的地方。根据Java方面的常规知识,我们知道通常画图是在一个Canvas对象上面进行的,由此,可以推知一个Surface对象中应该包含有一个Canvas对象,事实上的确如此
        
SurfaceView,顾名思义就是Surface的View,通过SurfaceView就可以看到Surface的部分或者全部的内容,下面用一个图来形象地描述一下Surface和SurfaceView的关系:

                                                                                                    

        SurfaceHolder是一个接口,其作用就像一个关于Surface的监听器。提供访问和控制SurfaceView背后的Surface 相关的方法 (providingaccess and control over this SurfaceView's underlying surface),它通过三个回调方法,让我们可以感知到Surface的创建、销毁或者改变。在SurfaceView中有一个方法getHolder,可以很方便地获得SurfaceView所对应的Surface所对应的SurfaceHolder
        surfaceHolder通过回到方法的方式,让我们可以感知到Surface的创建、销毁或者改变。其实这一点是通过其内部的静态子接口SurfaceHolder.Callback来实现的。SurfaceHolder.Callback中定义了三个接口方法:
         implements SurfaceHolder.Callback 需要实现的接口有如是3个方法

点击(此处)折叠或打开

  1. //当surface发生任何结构性的变化时(格式或者大小),该方法就会被立即调用。
  2. @Override
  3. public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
  4. // TODO Auto-generated method stub
  5. }

  6. //当surface对象创建后,该方法就会被立即调用。
  7. @Override
  8. public void surfaceCreated(SurfaceHolder arg0) {
  9. // TODO Auto-generated method stub
  10. }

  11. //当surface对象在将要销毁前,该方法会被立即调用。
  12. @Override
  13. public void surfaceDestroyed(SurfaceHolder arg0) {
  14. // TODO Auto-generated method stub
  15. }

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

    1.        abstract void (callback)

                    为SurfaceHolder添加一个SurfaceHolder.Callback回调接口。

    2.        abstract ()

                    获取一个Canvas对象,并锁定之。所得到的Canvas对象,其实就是Surface中一个成员。

    3.        abstract (dirty)

                    同上。但只锁定dirty所指定的矩形区域,因此效率更高。

    4.        abstract void (canvas)

                    当修改Surface中的数据完成后,释放同步锁,并提交改变,然后将新的数据进行展示,同时Surface中相关数据会被丢失。

     5.      public abstract void setType (int type)

                 设置Surface的类型,接收如下的参数:

                SURFACE_TYPE_NORMAL:用RAM缓存原生数据的普通Surface

                SURFACE_TYPE_HARDWARE:适用于DMA(Direct memory access )引擎和硬件加速的Surface

                SURFACE_TYPE_GPU:适用于GPU加速的Surface

                SURFACE_TYPE_PUSH_BUFFERS:表明该Surface不包含原生数据,Surface用到的数据由其他对象提供,在Camera图像览中就使用该类型的Surface,有Camera负责提供给预览Surface数据,这样图像预览会比较流畅。如果设置这种类型则就不能调用lockCanvas来获取Canvas对象了。需要注意的是,在高版本的Android SDK中,setType这个方法已经被depreciated了。

        2、3、4中的同步锁机制的目的,就是为了在绘制的过程中,Surface中的数据不会被改变。

        从设计模式的高度来看,Surface、SurfaceView和SurfaceHolder实质上就是广为人知的MVC。Mode就是这里的Surface;View即是这里的SurfaceView;SurfaceHolder可以理解为MVC中的Controller。这样看起来三者之间的关系就清楚了很多。

       SurfaceView目的之一,就是提供一个可以用另外一个线程(第二个线程)进行屏幕渲染的surface(译注:即UI线程和绘制线程可以分离)。如果你打算这样使用,那么应当注意一些线程方面的语义,所有SurfaceView和SurfaceHolder.Callback中声明的方法,必须在运行SurfaceView窗口中的线程中调用(典型地,就是应用的主线程。译注:即UI线程),因为它们需要正确地将同时被绘制线程访问的各种状态进行同步。必须保证,只有在背后的Surface有效的时候 – 在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()这两个方法调用之间,访问它。

下面是一个测试例子

代码来自http://www.cnblogs.com/xuling/archive/2011/06/06/android.html

点击(此处)折叠或打开

  1. package xl.test;

  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.graphics.Canvas;
  5. import android.graphics.Color;
  6. import android.graphics.Paint;
  7. import android.graphics.Rect;
  8. import android.os.Bundle;
  9. import android.view.SurfaceHolder;
  10. import android.view.SurfaceView;

  11. public class ViewTest extends Activity {
  12.     /** Called when the activity is first created. */
  13.     @Override
  14.     public void onCreate(Bundle savedInstanceState) {
  15.         super.onCreate(savedInstanceState);
  16.         setContentView(new MyView(this));
  17.     }
  18.     //视图内部类
  19.     class MyView extends SurfaceView implements SurfaceHolder.Callback
  20.     {
  21.         private SurfaceHolder holder;
  22.         private MyThread myThread;
  23.         public MyView(Context context) {
  24.             super(context);
  25.             // TODO Auto-generated constructor stub
  26.             holder = this.getHolder();
  27.             holder.addCallback(this);
  28.             myThread = new MyThread(holder);//创建一个绘图线程
  29.         }

  30.         @Override
  31.         public void surfaceChanged(SurfaceHolder holder, int format, int width,
  32.                 int height) {
  33.             // TODO Auto-generated method stub
  34.             
  35.         }

  36.         @Override
  37.         public void surfaceCreated(SurfaceHolder holder) {
  38.             // TODO Auto-generated method stub
  39.             myThread.isRun = true;
  40.             myThread.start();
  41.         }

  42.         @Override
  43.         public void surfaceDestroyed(SurfaceHolder holder) {
  44.             // TODO Auto-generated method stub
  45.             myThread.isRun = false;
  46.         }
  47.         
  48.     }
  49.     //线程内部类
  50.     class MyThread extends Thread
  51.     {
  52.         private SurfaceHolder holder;
  53.         public boolean isRun ;
  54.         public MyThread(SurfaceHolder holder)
  55.         {
  56.             this.holder =holder;
  57.             isRun = true;
  58.         }
  59.         @Override
  60.         public void run()
  61.         {
  62.             int count = 0;
  63.             while(isRun)
  64.             {
  65.                 Canvas c = null;
  66.                 try
  67.                 {
  68.                     synchronized (holder)
  69.                     {
  70.                         c = holder.lockCanvas();//锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。
  71.                         c.drawColor(Color.BLACK);//设置画布背景颜色
  72.                         Paint p = new Paint(); //创建画笔
  73.                         p.setColor(Color.WHITE);
  74.                         Rect r = new Rect(100, 50, 300, 250);
  75.                         c.drawRect(r, p);
  76.                         c.drawText("这是第"+(count++)+"秒", 100, 310, p);
  77.                         Thread.sleep(1000);//睡眠时间为1秒
  78.                     }
  79.                 }
  80.                 catch (Exception e) {
  81.                     // TODO: handle exception
  82.                     e.printStackTrace();
  83.                 }
  84.                 finally
  85.                 {
  86.                     if( null)
  87.                     {
  88.                         holder.unlockCanvasAndPost(c);//结束锁定画图,并提交改变。

  89.                     }
  90.                 }
  91.             }
  92.         }
  93.     }
  94. }



阅读(1499) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~