SurfaceHolder-----api的使用

SurfaceHolder

ZZZZZZZZZZ:http://blog.csdn.net/ainibaifenbai/article/details/6556632

版本:Android 2.2 r1

结构

继承关系

public interface SurfaceHolder

android.view.SurfaceHolder 

概述

抽象接口持有人显示表面。允许您控制面的大小和格式,编辑在suface的橡树,并监测到变化。此接口通常可通过SurfaceView来实现

当一个线程使用不同于正在运行的线程的SurfaceView的接口时,你应该仔细阅读lockCanvas()Callback.surfaceCreated()这两个抽象函数

常量值

public static final int SURFACE_TYPE_GPU 

常数已声明不赞成使用,已过时。

被忽略,该常量值在需要时自动设置。

Surface类型:创建适用于GPU加速的Surface 

常量值:2 (0x00000002)

public static final int SURFACE_TYPE_HARDWARE 

常数已声明不赞成使用,已过时。

被忽略,该常量值在需要时自动设置。

Surface类型:创建适用于DMA(Direct memory access )引擎和硬件加速的Surface 

常量值:1 (0x00000001) 

public static final int SURFACE_TYPE_NORMAL 

Surface类型:创建用RAM缓存原生数据的普通Surface  

常量值:0 (0x00000000

public static final int SURFACE_TYPE_PUSH_BUFFERS 

Surface类型:创建一个不包含原生数据Surface,Surface用到的数据由其他对象提供。如果设置这种类型则就不能调用lockCanvas来获取Canvas对象了,否则将出现错误。 

常量值:3 (0x00000003)  

公共方法

public abstract void addCallback (SurfaceHolder.Callback callback) 

Surface持有者添加回调接口,一个持有者可以关联多个回调接口。

参数

callback  新的回调接口  

public abstract Surface getSurface () 

直接获取Surface对象,这个Surface对象并不总是能获取的。

例如:当使用SurfaceView, Surface的持有者直到该View隶属于当前窗口管理器,确认布局大小和屏幕的位置后才进行创建,你通常需要实现Callback.surfaceCreated寻找出可用的Surface

注意,如果你通过另外的线程直接访问Surface ,关键在于你正确的实现了Callback.surfaceCreated Callback.surfaceDestroyed 函数来确保你访问的线程的Surface是可用的,有效的,当一个线程正在使用该Surface,将不能得到释放,销毁。

这个方法的目的是用于经常需要直接访问Surface对象的框架(通常是通过本地代码),在设计API时总使用SurfaceHolder来改变Surface,而不是Surface对象本身。一个经验规则是应用程序代码不能调用该方法

返回   

Surface对象

public abstract Rect  getSurfaceFrame () 

检索当前Surface的大小

注意:不能修改发挥矩形区域大小,这是唯一安全的调用从SurfaceView的窗口线程,否则就需要放在lockCanvas()里面调用。

返回

Suface的矩形尺寸,左侧和顶部总为0

 

public abstract boolean isCreating () 

使用这个方法是来确定在进程中的Surface是否通过Callback方法正被创建,这是为了确定surfaceChanged(SurfaceHolder, int, int, int).方法是否能用。

返回

True 进程里的Suface正被创建

public abstract Canvas lockCanvas () 

开始编辑surface的像素,返回可以用来画到表面的位图Canvas如果表面尚未建立或无法进行编辑返回null。通常需要实现Callback.surfaceCreated找出Surface方可使用。

Surface的内容再从调用unlockCanvas()  lockCanvas(),之间被保存,为此,在Surface区域内的没有个像素都将被画出,仅一个例外是当脏矩形被指定的时候,非脏像素将会被保存。

如果当Surface没有初始化(Callback.surfaceCreated之前或者Callback.surfaceDestroyed之后),你反复调用它,为了避免耗费CPU,这些调用将以缓慢的速度被杀死。

如果没有返回null值,这个函数在内部直到调用unlockCanvasAndPost(Canvas)函数,才持有锁,来防止SurfaceView在绘制的时候被创建,销毁,或者修改surface,因为当调用Callback.surfaceDestroyed你不需要创建一个特殊的同步绘制线程 所以你能更方便的直接访问这个Sufrace

返回

用来进行绘制的Canvas

public abstract Canvas lockCanvas (Rect dirty) 

lockCanvas()一样,但允许指定一个脏矩形,再这个矩形的每个像素都必须被绘制,脏矩形外的像素将被保存直到下次调用lockCanvas()

参数

dirty  将被修改的Surface区域

返回

用来进行绘制的Canvas

参见

lockCanvas ()

public abstract void removeCallback (SurfaceHolder.Callback callback) 

Surface持有者中删除先前添加的回调接口

参数

callback  要删除的回调接口  

public abstract void setFixedSize (int width, int height) 

使surface固定大小,他将永远不能该表大小,当和SurfaceView一起工作时,这必须被同一运行的SurfaceView的窗口线程来调用

参数

width  surface的宽

height  surface的高.  

public abstract void setFormat (int format) 

设置surface所需的像素格式。默认是不透明的,当和SurfaceView一起工作时,这必须被同一运行的SurfaceView的窗口线程来调用

参数 

format  PixelFormat的常量

参见

PixelFormat

public abstract void setKeepScreenOn (boolean screenOn) 

surface被显示的时候是否启用或禁用屏幕保持打开状态,默认是禁用,允许屏幕关闭,启用选项有效时,可以安全的调用任何线程。

参数 

screenOn  ture时强制屏幕保持打开状态,fasle允许气关闭

public abstract void setSizeFromLayout () 

允许suface基于容器的布局来改变大小(这是默认的),当启用此功能,就应该监视surfaceChanged(SurfaceHolder, int, int, int)应对suface的大小变化,当和SurfaceView一起工作时,这必须被同一运行的SurfaceView的窗口线程来调用

public abstract void setType (int type) 

设置该surface的类型

参数

type  surface的内存类型

public abstract void unlockCanvasAndPost (Canvas canvas) 

surface完成编辑像素,该函数调用后,surface的当前像素就会在屏幕上显示,但是它的数据会丢失,尤其是没有保证surface数据保持不变的时候再次调用lockCanvas()

参数

canvas  先前调用lockCanvas()返回的Canvas

参考

lockCanvas()

补充

在用SurfaceView进行游戏开发过程中,用到SurfaceHolder来处理它的Canvas上画的效果和动画是必不可少的。用于控制表面,大小,像素等。其中特别要注意以下的几个函数:
abstract void addCallback(SurfaceHolder.Callback callback);

// SurfaceView当前的持有者一个回调对象。

abstract Canvas lockCanvas();

// 锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。


abstract Canvas lockCanvas(Rect dirty);

// 锁定画布的某个区域进行画图等..因为画完图后,会调用下面的unlockCanvasAndPost来改变显示内容。
// 相对部分内存要求比较高的游戏来说,可以不用重画dirty外的其它区域的像素,可以提高速度。

abstract void unlockCanvasAndPost(Canvas canvas);
// 结束锁定画图,并提交改变。
  

在android中开发游戏,一般来说,或想写一个复杂一点的游戏,是必须用到SurfaceView来开发的。

经过这一阵子对android的学习,我找到了自已在android中游戏开发的误区,不要老想着用Layoutview去实现,不要将某个游戏

中的对象做成一个组件来处理。应该尽量想着在Canvas(画布)中画出游戏戏中的背景、人物、动画等...

SurfaceView提供直接访问一个可画图的界面,可以控制在界面顶部的子视图层。SurfaceView是提供给需要直接画像素而不是使用

窗体部件的应用使用的。Android图形系统中一个重要的概念和线索是surfaceView及其子类(如TextView, Button

要画在surface上。每个surface创建一个Canvas对象(但属性时常改变),用来管理viewsurface上的绘图操作,如画点画线。

还要注意的是,使用它的时候,一般都是出现在最顶层的

使用的SurfaceView的时候,一般情况下还要对其进行创建,销毁,改变时的情况进行监视,这就要用到SurfaceHolder.Callback.

例子

SurfaceView1.Java

package com.mxgsa.drawtest.view;

import java.util.Vector;

import com.mxgsa.drawtest.common.Utils;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Paint.Style;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

public class SurfaceView1 extends SurfaceView implements SurfaceHolder.Callback {

private SurfaceHolder sHolder = null;

private Vector<Float> xs = new Vector<Float>();

private Vector<Float> ys = new Vector<Float>();

private boolean isRun = true;

public SurfaceView1(Context context, AttributeSet attribute) {

super(context, attribute);

sHolder = getHolder();

sHolder.addCallback(this);

// TODO Auto-generated constructor stub

}

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

// TODO Auto-generated method stub

}

public void surfaceCreated(SurfaceHolder holder) {

// TODO Auto-generated method stub

new Thread(new MyLoop()).start();

}

public void surfaceDestroyed(SurfaceHolder holder) {

// TODO Auto-generated method stub

isRun = false;

Utils.showLog(this.getClass().getName(), "surfaceDestroyed");

}

@Override

protected void onDraw(Canvas canvas) {

// TODO Auto-generated method stub

super.onDraw(canvas);

canvas.drawColor(Color.WHITE);// 这里是绘制背景

Paint p = new Paint(); // 笔触

p.setAntiAlias(true); // 反锯齿

p.setColor(Color.BLACK);

p.setStyle(Style.STROKE);

for (int i = 0; i < xs.size(); i++)

canvas.drawCircle(xs.elementAt(i), ys.elementAt(i), 10, p);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

// TODO Auto-generated method stub

if (event.getAction() == MotionEvent.ACTION_DOWN) {

xs.add(event.getX());

ys.add(event.getY());

}

return true;

}

class MyLoop implements Runnable {

// 熟悉游戏编程的应该很面熟吧,主循环

public void run() {

Canvas c = null;

// TODO Auto-generated method stub

while (isRun) {

try {

synchronized (sHolder) {

c = sHolder.lockCanvas();

onDraw(c);

Thread.sleep(50);

}

catch (Exception e) {

finally {

if (c != null) {

sHolder.unlockCanvasAndPost(c);

}

}

}

}

}

}

MainActivity.Java

package com.mxgsa.drawtest;

import com.mxgsa.drawtest.view.SurfaceView1;

import android.app.Activity;

import android.os.Bundle;

public class MainActivity extends Activity {

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(new SurfaceView1(this,null));

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值