其实相当于MVC结构的三者关系:M(Surface)、V(SurfaceView)、C(SurfaceHolder)

1、Surface

Handle onto a raw buffer that is being managed by the screen compositor.

简单翻译:Surface是原始图像缓冲区(raw buffer)的一个句柄,而原始图像缓冲区是由屏幕图像合成器(screen compositor)管理的。包含两层意思:

(1)通过Surface(因为Surface是句柄)就可以获得原生缓冲器以及其中的内容。就像在C语言中,可以通过一个文件的句柄,就可以获得文件的内容一样;

(2)原生缓冲器(rawbuffer)是用于保存当前窗口的像素数据的;

(3)Surface中有一个Canvas成员,专门用于画图的。

可以认为Android中的Surface就是一个用来画图形(graphics)或图像(image)的地方。根据Java方面的常规知识,我们知道通常画图是在一个Canvas对象上面进行的,由此,可以推知一个Surface对象中应该包含有一个Canvas对象,事实上的确如此,而且这一点可以很容易通过debug运行程序的方式得到证明(将光标停留在对象变量surface上,会弹出一个对话框,其中红色方框的内容,就表面surface中有一个CompatileCanvas成员变量)。

所以,Surface中的Canvas成员,是专门用于供程序员画图的场所,就像黑板一样;其中的原生缓冲器是用来保存数据的地方;Surface本身的作用类似一个句柄,得到了这个句柄就可以得到其中的Canvas、原生缓冲器以及其它方面的内容。

 2、SurfaceView

SurfaceView,顾名思义就是Surface的View,通过SurfaceView就可以看到Surface的部分或者全部的内容,下面用一个图来形象地描述一下Surface和SurfaceView的关系:

可以看到,SurfaceView有两层含义:

(1)视图窗口(ViewPort)的意思;

(2)是View的派生类。

在Android中Surface是从Object派生而来,且实现了Parcelable接口。看到Parcelable就让人能很自然地想到数据容器,SurfaceView就是用来展示Surface中的数据的。在这个层面上而言,Surface就是管理数据的地方,SurfaceView就是展示数据的地方。

3、SurfaceHolder

Abstract interface to someone holding a display surface. Allows you to control the surface size and format, edit the pixels in the surface, and monitor changes to the surface. This interface is typically available through theSurfaceView class.

简单翻译:SurfaceHolder是控制surface的一个抽象接口,你可以通过SurfaceHolder来控制surface的尺寸和格式,或者修改surface的像素,监视surface的变化等等,SurfaceHolder是SurfaceView的典型接口。与直接控制SurfaceView来修改surface不同,使用SurfaceHolder来修改surface时,需要注意lockCanvas() 和Callback.surfaceCreated()这两个方法。

SurfaceHolder是一个接口,其作用就像一个关于Surface的监听器。提供访问和控制SurfaceView背后的Surface 相关的方法 (providingaccess and control over this SurfaceView's underlying surface),它通过三个回调方法,让我们可以感知到Surface的创建、销毁或者改变。在SurfaceView中有一个方法getHolder,可以很方便地获得SurfaceView所对应的Surface所对应的SurfaceHolder。

4、SurfaceHolder.Callback

前面已经讲到SurfaceHolder是一个接口,它通过回到方法的方式,让我们可以感知到Surface的创建、销毁或者改变。其实这一点是通过其内部的静态子接口SurfaceHolder.Callback来实现的。surfaceCreated、surfaceChanged、surfaceDestroyed。

这个类的目的之一,就是提供一个可以用另外一个线程(第二个线程)进行屏幕渲染的surface(即UI线程和绘制线程可以分离)。如果你打算这样使用,那么应当注意一些线程方面的语义:

--> 所有SurfaceView和SurfaceHolder.Callback中声明的方法,必须在运行SurfaceView窗口中的线程中调用(典型地,就是应用的主线程,即UI线程),因为它们需要正确地将同时被绘制线程访问的各种状态进行同步。

--> 必须保证,只有在背后的Surface有效的时候 – 在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()这两个方法调用之间,访问它。

5、一个简单的例子体验一下

 public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MySurfaceView(this));
}
} // ===================================== public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private MyThread mThread; public MySurfaceView(Context context) {
super(context);
this.mHolder = this.getHolder();
this.mHolder.addCallback(this);
this.mThread = new MyThread(mHolder);
} @Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
Log.d("[KLH]", "surfaceChanged(" + i + ", " + i1 + ", " + i2 + ")");
} @Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.d("[KLH]", "surfaceCreated()"); this.mThread.setRun(true);
this.mThread.start();
} @Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
Log.d("[KLH]", "surfaceDestroyed()"); this.mThread.setRun(false);
}
} // ===================================== public class MyThread extends Thread {
private SurfaceHolder mHolder;
private boolean mRun; public MyThread(SurfaceHolder h) {
this.mHolder = h;
this.mRun = true;
} @Override
public void run() {
int counter = 0;
Canvas canvas = null;
while (mRun) {
try {
canvas = this.mHolder.lockCanvas();
canvas.drawColor(Color.WHITE); Paint p = new Paint();
if (counter % 2 == 0){
p.setColor(Color.BLACK);
} else {
p.setColor(Color.RED);
}
p.setTextSize(30); Rect r = new Rect(100, 50, 380, 300); // Begin paint
canvas.drawRect(r, p);
canvas.drawText("Interval=" + (counter++) + " seconds.", 100, 410, p);
Thread.sleep(1000);
} catch (Exception run) {
run.printStackTrace();
} finally {
if (canvas != null) {
this.mHolder.unlockCanvasAndPost(canvas);
}
}
}
} public boolean isRun() {
return this.mRun;
} public void setRun(boolean r) {
this.mRun = r;
}
}

[Android] Surface、SurfaceHolder与SurfaceView的更多相关文章

  1. Android中的Surface, SurfaceHolder, SurfaceHolder.Callback, SurfaceView

    传入一个surface,然后让openGL在surface上画图 window->view hierachy(DecorView是tree的root)->ViewRoot->Surf ...

  2. android大扫盲之SurfaceView,SurfaceHolder,SurfaceHolder.CallBack

    最近接触到了SurfaceView,SurfaceHolder,SurfaceHolder.CallBack,一直不求其解,现在来粗浅认识一下它们. 先看一下官方的定义: 1.SurfaceView ...

  3. Android 学习笔记之SurfaceView的使用+如何实现视频播放...

    学习内容: 1.掌握Surface的使用... 2.Android中如何实现视频播放... 1.SurfaceView类的使用   在Android中,一般播放音频时我们可以去使用Android提供的 ...

  4. 转:android surface简单使用Demo

    转: http://blog.csdn.net/listening_music/article/details/6860786 通过之前介绍的如何自定义View, 我们知道使用它可以做一些简单的动画效 ...

  5. Android实时取景:用SurfaceView实现

    对于基于摄像头的Android应用,实时取景是一个基本前提,通过前置或后置摄像头持续获取捕获到的内容,可以进一步做处理(人脸检测.美颜.滤镜等). 所谓实时取景,简单说就是调用android的摄像头, ...

  6. Android之View和SurfaceView

    Android之View和SurfaceView Android游戏当中主要的除了控制类外就是显示类View.SurfaceView是从View基类中派生出来的显示类.android游戏开发中常用的三 ...

  7. 玩转Android Camera开发(一):Surfaceview预览Camera,基础拍照功能完整demo

    杂家前文是在2012年的除夕之夜仓促完成,后来很多人指出了一些问题,琐事缠身一直没有进行升级.后来随着我自己的使用,越来越发现不出个升级版的demo是不行了.有时候就连我自己用这个demo测一些性能. ...

  8. Android Button悬浮在SurfaceView上

    实现Button悬浮于与SurfaceView之上实现 注意:你实现的SurfaceView和android中的Button,EditView是同级的,不能把一个包含在另一个里面 1.创建自己的Sur ...

  9. 【转】Android Fragment中使用SurfaceView切换时闪一下黑屏的解决办法

    重构了下之前自己的一个新闻客户端,全部使用了Fragment来进行页面切换,只有一个入口Activity作为程序的启动Activity,其中有一个界面需要调用摄像头识别二维码, 于是就会用到Surfa ...

随机推荐

  1. 安装最新nginx

    另外:http://nginx.org/en/linux_packages.html#mainline https://blog.csdn.net/hiram/article/details/5178 ...

  2. WCF 添加服务引用 HTTP 请求已超过为 00:00:00 分配的超时。为此操作分配的时间可能是较长超时

    今天在用公司的笔记本引用WCF的时候,处于一直等待的过程,一直在下载信息,一直等了很长时间,弹出了一个消息 下载“http://ip:8085/xxxxx/xxxxx/mex/$metadata”时出 ...

  3. C#LinQ语法

    Unity开发VR之Vuforia 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...

  4. xdoj 1237 (贪心+逆向思维)

    提示:  当有的元素分裂的同时,其他元素也可以+1 分析: 逆向思维,把当前数列变成一个0: 相应得操作相反: 每个元素减1 相同得两个元素可以合并 设数列中最大的数是max,则一共需要减max次才可 ...

  5. python基础-函数基本特性和用法

    函数: 初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因变量,y是x的函数.自变量x的取值 ...

  6. 聊聊 CAS

    哥有故事,你有酒,长夜漫漫,听我给你说. 参考资源: https://blog.csdn.net/hsuxu/article/details/9467651 1.概述 CAS,compare and ...

  7. python------模块定义、导入、优化 ------->sys模块,shutil模块

    1.sys模块 import sys sys.argv #命令行参数List,第一个元素是程序本身路径sys.exit(n) #退出程序,正常退出时exit(0).sys.version #获取Pyt ...

  8. linux30道运维面试题

    传送门https://zhangge.net/1986.html

  9. replicatedhq-ship 基于Kustomize 项目的快速kubernetes 应用部署工具

    replicatedhq-ship 是对Kustomize 项目的扩展,我们可以用它来快速的进行三方应用的管理部署, 可以和helm,kubernetes 清单文件,knative 集成,我们可以方便 ...

  10. 使用kubebapps 管理helm 仓库已经应用使用Monocular专门提供helm 仓库查找

    Monocular 从1.0 开始专注于helm 的UI展示,对于部署以及维护已经去掉了,官方也提供了相关的说明以及 推荐了几个可选的部署工具,从使用以及架构上来说kubeapps 就是Monocul ...