Surface、SurfaceView、SurfaceHolder及SurfaceHold。。。

更新时间:2023-07-08 06:14:45 阅读: 评论:0

Surface、SurfaceView、SurfaceHolder及SurfaceHold。。。⼀、Surface
Surface就是“表⾯”的意思。在SDK的⽂档中,对Surface的描述是这样的:“Handle onto a raw buffer that is being managed by the screen compositor”,翻译成中⽂就是“由屏幕显⽰内容合成器(screen compositor)所管理的原⽣缓冲器的句柄”,这句话包括下⾯两个意思:
1.      通过Surface(因为Surface是句柄)就可以获得原⽣缓冲器以及其中的内容。就像在C语⾔中,可以通过⼀个⽂件的句柄,就可以获得⽂件的内容⼀样;
2.      原⽣缓冲器(rawbuffer)是⽤于保存当前窗⼝的像素数据的。
引伸地,可以认为Android中的Surface就是⼀个⽤来画图形(graphics)或图像(image)的地⽅。根据Java⽅⾯的常规知识,我们知道通常画图是在⼀个Canvas对象上⾯进⾏的,由此,可以推知⼀个Surface对象中应该包含有⼀个Canvas对象,事实上的确如此,⽽且这⼀点可以很容易通过debug运⾏程序的⽅式得到证明(将光标停留在对象变量surface上,会弹出⼀个对话框,其中红⾊⽅框的内容,就表⾯surface中有⼀个CompatileCanvas成员变量)当然,看源代码也是可以证明这⼀点:
因此,在前⾯提及的两个意思的基础上,可以再加上⼀条:
人力资源hr3.      Surface中有⼀个Canvas成员,专门⽤于画图的。
所以,Surface中的Canvas成员,是专门⽤于供程序员画图的场所,就像⿊板⼀样;其中的原⽣缓冲器是⽤来保存数据的地⽅;Surface本⾝的作⽤类似⼀个句柄,得到了这个句柄就可以得到其中的Canvas、原⽣缓冲器以及其它⽅⾯的内容。
⼆、SurfaceView
SurfaceView,顾名思义就是Surface的View,通过SurfaceView就可以看到Surface的部分或者全部的内容,下⾯⽤⼀个图来形象地描述⼀下Surface和SurfaceView的关系:
也就是说,Surface是⽤通过SurfaceView才能展⽰其中的内容。从这个意思上来说,SurfaceView中的View之确切的含义应该是viewport即“视⼝”的意思,做过数据库设计的朋友知道,假定⼀个数据表有20个字段,但我们常常只⽤到其中的5个字段,那么就可以在原数据表的基础上,通过SQL语句CREATEVIEW来创建只包含那5个字段内容的view。
另⼀⽅⾯,SurfaceView是Android中View的⼦类。事实上,在Android中所有⽤于界⾯展⽰的类皆为View的⼦类,包括那些不可见的、各种各样的Layout。
所以说,SurfaceView中的View有两个含义:
1.      视⼝(viewport)的意思
2.      SurfaceView是View的派⽣类
在Android中Surface是从Object派⽣⽽来,且实现了Parcelable接⼝。看到Parcelable就让⼈能很⾃然地想到数据容器,SurfaceView就是⽤来展⽰Surface中的数据的。在这个层⾯上⽽
⾔,Surface就是管理数据的地⽅,SurfaceView就是展⽰数据的地⽅。
三、SurfaceHolder
SurfaceHolder是⼀个接⼝,其作⽤就像⼀个关于Surface的监听器。提供访问和控制SurfaceView背后的Surface 相关的⽅法 (providingaccess and control over this SurfaceView's underlying surface),它通过三个回调⽅法,让我们可以感知到Surface的创建、销毁或者改变。在SurfaceView中有⼀个⽅法getHolder,可以很⽅便地获得SurfaceView所对应的Surface所对应的SurfaceHolder(有点拗⼝吧)。
除下⾯将要提到的SurfaceHolder.Callback外,SurfaceHolder还提供了很多重要的⽅法,其中最重要的就是:
1.        abstract void addCallback(SurfaceHolder.Callbackcallback)
为SurfaceHolder添加⼀个SurfaceHolder.Callback回调接⼝。
smynes2.        abstract Canvas lockCanvas()
获取⼀个Canvas对象,并锁定之。所得到的Canvas对象,其实就是Surface中⼀个成员。
3.        abstract Canvas lockCanvas(Rectdirty)
同上。但只锁定dirty所指定的矩形区域,因此效率更⾼。
4.        abstract void unlockCanvasAndPost(Canvascanvas)
当修改Surface中的数据完成后,释放同步锁,并提交改变,然后将新的数据进⾏展⽰,同时Surface中相关数据会被丢失。
5.      public abstract void tType (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中,tType这个⽅法已经被depreciated了。
2、3、4中的同步锁机制的⽬的,就是为了在绘制的过程中,Surface中的数据不会被改变。
从设计模式的⾼度来看,Surface、SurfaceView和SurfaceHolder实质上就是⼴为⼈知的MVC,即Model-View-Controller。Model就是模型的意思,或者说是数据模型,或者更简单地说就是数据,也就是这⾥的Surface;View即视图,代表⽤户交互界⾯,也就是这⾥的SurfaceView;SurfaceHolder很明显可以理解为MVC中的Controller(控制器)。这样看起来三者之间的关系就清楚了很多。
四、SurfaceHolder.Callback
前⾯已经讲到SurfaceHolder是⼀个接⼝,它通过回到⽅法的⽅式,让我们可以感知到Surface的创建、销毁或者改变。其实这⼀点是通过其内部的静态⼦接⼝SurfaceHolder.Callback来实现的。SurfaceHolder.Callback中定义了三个接⼝⽅法:
1.    abstract void surfaceChanged(SurfaceHolderholder, int format, int width, int height)
当surface发⽣任何结构性的变化时(格式或者⼤⼩),该⽅法就会被⽴即调⽤。
2.      abstract void surfaceCreated(SurfaceHolderholder)
当surface对象创建后,该⽅法就会被⽴即调⽤。
3.      abstract void surfaceDestroyed(SurfaceHolderholder)
数据调查
当surface对象在将要销毁前,该⽅法会被⽴即调⽤。
在Android SDK⽂档中,关于SurfaceView的描述⾥⾯,有⼀段这样的话:
One of the purpos of this class is to provide a surface in which a condarythread can render into the screen. If you are going to u it this way, youneed to be aware of some threading mantics:
-        All SurfaceView and SurfaceHolder.Callbackmethods will be called from the thread running the SurfaceView's window(typically the main thread of the application). They thus need to correctlysynchronize with any state that is also touched by the drawing thread.
-      You must ensure that the drawingthread only touches the underlying Surface while it is valid -- betweenSurfaceHolder.Callback.surfaceCreated()高清壁纸平板
andSurfaceHolder.Callback.surfaceDestroyed().
这段话很重要,⼤致意思如下:
这个类的⽬的之⼀,就是提供⼀个可以⽤另外⼀个线程(第⼆个线程)进⾏屏幕渲染的surface(译注:即UI线程和绘制线程可以分离)。如果你打算这样使⽤,那么应当注意⼀些线程⽅⾯的语义:
-          所有SurfaceView和SurfaceHolder.Callback中声明的⽅法,必须在运⾏SurfaceView窗⼝中的线程中调⽤(典型地,就是应⽤的主线程。译注:即UI线程),因为它们需要正确地将同时被绘制线程访问的各种状态进⾏同步。
-          必须保证,只有在背后的Surface有效的时候 – 在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()这两个⽅法调⽤之间,访问它。
陈述句大全1.        在Eclip中创建⼀个Android Project项⽬TestSurfaceView,并选择⽣成缺省的Activity TestSurfaceViewActivity
2.        创建⼀个绘制线程如下:
package stsurfaceview;
aphics.Canvas;
aphics.Color;
aphics.Paint;
aphics.Rect;
importandroid.view.SurfaceHolder;
// 绘制线程
public class MyThread extendsThread
{
private SurfaceHolder holder;
private boolean run;
public MyThread(SurfaceHolder holder)
{
this.holder = holder;
run = true;
}
@Override
public void run()
{
int counter = 0;
Canvas canvas = null;
while(run)
{
/
/ 具体绘制⼯作
try
{
// 获取Canvas对象,并锁定之
canvas= holder.lockCanvas();
// 设定Canvas对象的背景颜⾊
canvas.drawColor(Color.WHITE);
// 创建画笔
Paintp = new Paint();
// 设置画笔颜⾊
p.tColor(Color.BLACK);
/
/ 设置⽂字⼤⼩
p.tTextSize(30);
// 创建⼀个Rect对象rect
Rect rect = new Rect(100, 50, 380, 330);
// 在canvas上绘制rect
canvas.drawRect(rect,p);
// 在canvas上显⽰时间
少年游歌曲
canvas.drawText("Interval = " + (counter++) + " conds.", 100, 410, p);
Thread.sleep(1000);
}
catch(Exception e)
{
{
e.printStackTrace();
}
finally
{
if(canvas != null)
{
// 解除锁定,并提交修改内容
holder.unlockCanvasAndPost(canvas);
}
}
}
}
public boolean isRun()
{
return run;
}
public void tRun(boolean run)
{
伊莱克斯洗衣机
this.run = run;
}
}
3.      ⾃定义⼀个SurfaceView类如下:
package stsurfaceview;
t.Context;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MySurfaceView extends SurfaceView
implements
SurfaceHolder.Callback
{
private SurfaceHolder holder;
private MyThread myThread;
publicMySurfaceView(Context context)
{
super(context);
// 通过SurfaceView获得SurfaceHolder对象
种田文小说
holder = getHolder();
// 为holder添加回调结构SurfaceHolder.Callback
holder.addCallback(this);
// 创建⼀个绘制线程,将holder对象作为参数传⼊,这样在绘制线程中就可以获得holder                    // 对象,进⽽在绘制线程中可以通过holder对象获得Canvas对象,并在Canvas上进⾏绘制                  myThread = new MyThread(holder);
}
// 实现SurfaceHolder.Callback接⼝中的三个⽅法,都是在主线程中调⽤,⽽不是在绘制线程中调⽤的        @Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
}
@Override
public void surfaceCreated(SurfaceHolder holder)
{
// 启动线程。当这个⽅法调⽤时,说明Surface已经有效了
myThread.tRun(true);
myThread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolderholder)
{
// 结束线程。当这个⽅法调⽤时,说明Surface即将要被销毁了
myThread.tRun(fal);
}
}
4.    修改TestSurfaceViewActivity.java代码,使之如下:

本文发布于:2023-07-08 06:14:45,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1072563.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:线程   对象   数据   绘制   创建   意思   内容
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图