`
java-mans
  • 浏览: 11667895 次
文章分类
社区版块
存档分类
最新评论

Android图形系统之Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的联系

 
阅读更多

/********************************************************************************************
* author:conowen@大钟
* E-mail:conowen@hotmail.com
* http://blog.csdn.net/conowen
* 注:本文为原创,仅作为学习交流使用,转载请标明作者及出处。

********************************************************************************************/


1、Surface


Surface

extends Object
implements Parcelable
java.lang.Object
android.view.Surface

Class Overview


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

简单翻译:

Surface是原始图像缓冲区(raw buffer)的一个句柄,而原始图像缓冲区是由屏幕图像合成器(screen compositor)管理的。




1.1、 就如在C语言编程一样,通过一个文件的句柄,就可以操作文件,获取文件的内容。 同样的,通过Surface就可以获取raw buffer其中的内容。原生缓冲区(raw buffer)存储着当前窗口的像素数据。


1.2、事实上,当得到一个Surface对象时,同时会得到一个Canvas(画布)对象。这一点可以通过查看\frameworks\base\core\java\android\view\Surface.java文件可知道Surface类定义了一个Canvas成员变量


    //@\frameworks\base\core\java\android\view\Surface.java
    // The mSurfaceControl will only be present for Surfaces used by the window
    // server or system processes. When this class is parceled we defer to the
    // mSurfaceControl to do the parceling. Otherwise we parcel the
    // mNativeSurface.
    private int mSurfaceControl;
    private int mSaveCount;
    private Canvas mCanvas;
    private int mNativeSurface;
    private int mSurfaceGenerationId;
    private String mName;

1.3、 理解Canvas对象,可以把它当做画布,Canvas的方法大多数是设置画布的大小、形状、画布背景颜色等等,要想在画布上面画画,一般要与Paint对象结合使用,顾名思义,Paint就是画笔的风格,颜料的色彩之类的。

        // 创建画笔  
        Paint paint = new Paint();  
        paint.setColor(Color.RED);// 设置红色  

        canvas.drawCircle(60, 20, 10, paint);// 画一个圆  


1.4、Surface本身的作用类似一个句柄,得到了这个句柄就可以得到其中的Canvas、原生缓冲器以及其它方面的内容。


1.5、Surface实现了Parcelable接口,(implements Parcelable),也就是说Surface对象可以把显示内容的数据写入到 Parcel 中,并且能够从Parcel读回数据。

Parcelable

android.os.Parcelable
Known Indirect Subclasses

Class Overview


Interface for classes whose instances can be written to and restored from a Parcel. Classes implementing the Parcelable interface must also have a static field calledCREATOR, which is an object implementing theParcelable.Creator interface.

简单翻译:
实现这个接口的对象可以写入数据到Parcel,同时也可以把数据读出来。



2、SurfaceView


SurfaceView

extends View
java.lang.Object
android.view.View
android.view.SurfaceView
Known Direct Subclasses

Class Overview


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 callinggetHolder().

The Surface will be created for you while the SurfaceView's window is visible; you should implementsurfaceCreated(SurfaceHolder) andsurfaceDestroyed(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 into the screen. If you are going to use it this way, you need to be aware of some threading semantics:

简单翻译:

SurfaceView提供了一个专门用于绘制的surface,这个surface内嵌于。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface在屏幕的正确绘制位置。

surface是Z-ordered的(也就是说在xyz坐标系中,按照Z坐标排序的,Z值大的表面覆盖在Z值小的表面的上方)这表明它总在自己所在窗口的后面。surfaceview在显示窗口处为Surface提供了一个可见区域,通过这个区域,才能看到Surface里面的内容。可以放置一些覆盖图层(overlays)在Surface上面,如Button、Textview之类的。但是,需要注意的是,如果Surface上面有全透明的控件,那么随着Surface的每一次变化,这些全透明的控件就会重新渲染,这样的话,就影响性能与显示的效果。

你可以通过SurfaceHolder这个接口去访问Surface,而执行getHolder()方法可以得到SurfaceHolder接口。

当SurfaceView的窗口可见时,Surface就会被创建,当SurfaceView窗口隐藏时,Surface就会被销毁。当然了,你也可以通过复写surfaceCreated(SurfaceHolder)surfaceDestroyed(SurfaceHolder) 这两个方法来验证一下Surface何时被创建与何时被销毁。

SurfaceView提供了一个运行在渲染线程的surface,若你要更新屏幕,你需要了解以下线程知识。



2.1、SurfaceView与Surface的联系

简单来说,SurfaceView与Surface的联系就是,Surface是管理显示内容的数据(implementsParcelable),包括存储于数据的交换。而SurfaceView就是把这些数据显示出来到屏幕上面。

两者联系如图所示:



3、SurfaceHolder


SurfaceHolder

android.view.SurfaceHolder

Class Overview


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.

When using this interface from a thread other than the one running its SurfaceView, you will want to carefully read the methodslockCanvas() andCallback.surfaceCreated().

简单翻译:

SurfaceHolder是控制surface的一个抽象接口,你可以通过SurfaceHolder来控制surface的尺寸和格式,或者修改surface的像素,监视surface的变化等等,SurfaceHolder是SurfaceView的典型接口。

与直接控制SurfaceView来修改surface不同,使用SurfaceHolder来修改surface时,需要注意lockCanvas()Callback.surfaceCreated().这两个方法。

SurfaceHolder控制surface的流程所使用的几个方法。

3.1、abstract void addCallback(SurfaceHolder.Callback callback)
Add a Callback interface for this holder.// 给SurfaceHolder一个回调对象。

3.2、abstract Canvas lockCanvas(Rect dirty)
Just like lockCanvas() but allows specification of a dirty rectangle.
// 锁定画布中的某一个区域,返回的画布对象Canvas(当更新的内容只有一个区域时,同时要追求高效,可以只更
新一部分的区域,而不必更新全部画布区域)

3.3、abstract Canvas lockCanvas()
Start editing the pixels in the surface.// 锁定画布,返回的画布对象Canvas

3.4、abstract void removeCallback(SurfaceHolder.Callback callback)
Removes a previously added Callback interface from this holder.//移除回调对象

3.5、abstract void unlockCanvasAndPost(Canvas canvas)
Finish editing pixels in the surface.// 结束锁定画图,并提交改变。

4、SurfaceHolder.Callback

SurfaceHolder.Callback

android.view.SurfaceHolder.Callback
Known Indirect Subclasses

Class Overview


A client may implement this interface to receive information about changes to the surface. When used with aSurfaceView, the Surface being held is only available between calls tosurfaceCreated(SurfaceHolder) andsurfaceDestroyed(SurfaceHolder). The Callback is set withSurfaceHolder.addCallback method.

简单翻译:

SurfaceHolder.Callback是监听surface改变的一个接口

4.1、public abstract voidsurfaceChanged(SurfaceHolder holder, int format, int width, int height)

holder format width height
The SurfaceHolder whose surface has changed.
The new PixelFormat of the surface.
The new width of the surface.
The new height of the surfa
//surface发生改变时被调用


4.2、public abstract voidsurfaceCreated(SurfaceHolder holder)

Parameters
holder
The SurfaceHolder whose surface is being created

//在surface创建时被调用,一般在这个方法里面开启渲染屏幕的线程。


4.3、public abstract voidsurfaceDestroyed(SurfaceHolder holder)

Parameters
holder
The SurfaceHolder whose surface is being destroyed.
//销毁时被调用,一般在这个方法里将渲染的线程停止。


附上上述所说几种的联系方法

SurfaceHolder = SurfaceView.getHolder();

Surface = SurfaceHolder.getSurface();

Canvas =SurfaceHolder.LockCanvas(Rect dirty)

Canvas   =Surface.lockCanvas(Rect dirty)


5、Demo小程序

共有两个class效果图如下,具体看代码和注释。


进入程序,执行

public void surfaceCreated(SurfaceHolder holder)

然后执行

public void surfaceChanged(SurfaceHolder holder, int format, int width,  int height)

退出程序调用surfaceDestroyed,释放资源。

public void surfaceDestroyed(SurfaceHolder holder)




/****************************************************************/

效果图:


@MySurfaceView.java

/*
 * author: conowen
 * e-mail: conowen@hotmail.com
 * date  :  2012.8.4
 */
package com.conowen.SurfaceViewDemo;

import android.app.Activity;
import android.os.Bundle;

public class SurfaceViewDemoActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // setContentView(R.layout.main);
        setContentView(new MySurfaceView(this));
        
    }
}



@SurfaceViewDemoActivity.java

/*
 * author: conowen
 * e-mail: conowen@hotmail.com
 * date  :  2012.8.4
 */
package com.conowen.SurfaceViewDemo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MySurfaceView extends SurfaceView implements
		SurfaceHolder.Callback {

	private String TAG = "conowen";
	
	private SurfaceHolder sfh;
	private boolean ThreadFlag;
	private int counter;
	private Canvas canvas;

	private Thread mThread = new Thread(new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			while (ThreadFlag) {

				// 锁定画布,得到Canvas对象
				canvas = sfh.lockCanvas();

				// 设定Canvas对象的背景颜色
				canvas.drawColor(Color.GREEN);

				// 创建画笔
				Paint p = new Paint();
				// 设置画笔颜色
				p.setColor(Color.RED);
				// 设置文字大小
				p.setTextSize(40);

				// 创建一个Rect对象rect
				// public Rect (int left, int top, int right, int bottom)
				Rect rect = new Rect(100, 50, 400, 350);
				// 在canvas上绘制rect
				canvas.drawRect(rect, p);
				// 在canvas上显示时间
				// public void drawText (String text, float x, float y, Paint
				// paint)
				canvas.drawText("时间 = " + (counter++) + " 秒", 500, 200, p);

				if (canvas != null) {
					// 解除锁定,并提交修改内容,更新屏幕
					sfh.unlockCanvasAndPost(canvas);
				}
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

	});

	public MySurfaceView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub

		// 通过SurfaceView获得SurfaceHolder对象
		sfh = this.getHolder();

		// 为SurfaceHolder添加回调结构SurfaceHolder.Callback
		sfh.addCallback(this);

	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub
		Log.i(TAG, "surfaceChanged");

	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		Log.i(TAG, "surfaceCreated");
		counter = 0;
		ThreadFlag = true;
		mThread.start();

	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		Log.i(TAG, "surfaceDestroyed");
		ThreadFlag = false;

	}

}




分享到:
评论

相关推荐

    AndroidApp中使用SurfaceView制作多线程动画的实例讲解.docx

    这意味着在`SurfaceHolder.Callback.surfaceCreated()`与`SurfaceHolder.Callback.surfaceDestroyed()`之间的时间段内,以及当`Surface`类型为`SURFACE_TYPE_PUSH_BUFFERS`时,才可以进行绘制操作。 3. **资源管理*...

    SurfaceView-Sample-master.zip_android_surfaceview

    SurfaceView是Android系统提供的一种特殊视图,它提供了与硬件底层交互的能力,能够实现高效的离屏渲染和双缓冲,使得开发者可以在独立于UI主线程的单独线程中进行图形绘制,从而避免阻塞UI更新,提升应用程序的性能...

    Android应用源码之(SurfaceView游戏框架).zip

    本资源"Android应用源码之(SurfaceView游戏框架).zip"可能包含一个使用SurfaceView构建的游戏框架示例,这对于学习如何在Android平台上高效地处理图形和游戏逻辑非常有帮助。 首先,SurfaceView与普通的View不同,...

    android之surfaceview学习示例

    在Android开发中,SurfaceView是一个非常重要的视图组件,它为开发者提供了在应用程序中实现高性能图形渲染的能力。SurfaceView的设计初衷是为了处理那些需要频繁更新且对性能要求较高的场景,如视频播放、游戏画面...

    android 调用系统摄像头和SurfaceView摄像头拍照

    在Android开发中,调用系统摄像头以及通过SurfaceView实现自定义相机功能是常见的需求。本文将详细介绍这两个知识点,包括如何启动系统相机应用以及如何利用SurfaceView进行相机预览和拍照。 首先,调用系统摄像头...

    SurfaceView实现幸运大抽奖.rar

    这个示例可以作为一个学习SurfaceView动画机制和实现复杂UI交互的起点,通过分析和修改代码,开发者可以加深对Android图形系统和多线程编程的理解。 总之,“SurfaceView实现幸运大抽奖.rar”提供的项目是一个学习...

    基于android实现SurfaceView播放视频代码.rar

    首先,SurfaceView是Android系统提供的一种特殊的视图,它允许开发者创建一个独立于UI线程的渲染表面,特别适合于显示高性能的图形或者视频内容。在视频播放场景中,SurfaceView可以高效地处理视频帧,避免因为UI...

    Android下使用SurfaceView播放视频文件

    在Android平台上,SurfaceView是一种特殊的视图,常用于处理高性能的图形渲染,比如播放视频或者游戏画面。在视频播放场景中,SurfaceView提供了一个高效且低延迟的显示机制,能够将视频帧直接绘制到Surface上,减少...

    Android提高第三篇之SurfaceView与多线程的混搭.docx

    在Android开发中,SurfaceView是一种特殊的视图,它允许开发者在单独的线程中进行高效地绘制操作,常用于创建高性能的图形界面,如游戏或视频播放。在本篇文章中,我们将深入探讨如何将SurfaceView与多线程相结合,...

    应用源码之(SurfaceView游戏框架).zip

    它的内部有一个单独的Surface,这个Surface是由一个单独的线程(称为SurfaceHolder.Callback)来更新的,这使得SurfaceView可以在不影响UI主线程的情况下进行高频率的绘图操作,非常适合用于游戏或者视频播放等需要...

    Android中SurfaceView截屏

    1. **捕获Surface内容**:由于`SurfaceView`的绘制不在主线程,我们需要在Surface的回调函数`SurfaceHolder.Callback`的`surfaceChanged()`或`surfaceCreated()`中捕获绘制内容。可以创建一个`Bitmap`对象,然后使用...

    Android SurfaceView 实现图片缩放 滑动

    在Android开发中,SurfaceView是一种特殊的视图,它允许开发者创建高性能的图形界面,尤其适合处理视频播放或游戏等需要连续刷新的场景。本话题主要探讨如何利用SurfaceView实现图片的缩放和滑动功能。 首先,理解...

    android SurfaceView添加线程源码

    首先,`SurfaceView`的特性之一是它拥有自己的后台渲染线程,这个线程通常被称为`SurfaceHolder.Callback`线程。当创建`SurfaceView`时,系统会自动为它创建一个`Surface`对象,这个`Surface`就是用于绘制的地方。`...

    SurfaceView小例子

    总的来说,这个"SurfaceView小例子"通过一个趣味的场景,帮助开发者掌握如何在Android中利用SurfaceView进行高效图形处理,理解Surface、SurfaceHolder和SurfaceHolder.Callback的角色和交互方式,以及如何实现双...

    android中surfaceview控件的使用范例

    SurfaceView是Android系统提供的一种特殊视图,它拥有一个独立于应用程序主线程的Surface,可以在后台线程中进行绘图操作,从而避免阻塞UI线程。SurfaceView由两部分组成:一个是View,显示在界面上;另一个是...

    Android SurfaceView使用Demo

    `SurfaceView` 是 Android 系统提供的一种特殊的视图组件,它允许开发者在应用程序中创建高性能的图形界面,比如游戏、视频播放器等需要连续更新图像的应用。`SurfaceView` 提供了一个独立于应用程序主线程的绘制...

    android SurfaceView的基本用法

    在Android开发中,SurfaceView是一个非常重要的视图组件,它为高效显示动态视频或复杂的2D/3D图形提供了一个平台。SurfaceView拥有自己的独立渲染表面,与主线程的UI更新分离,使得高性能的图像处理成为可能。接下来...

Global site tag (gtag.js) - Google Analytics