61阅读

surfaceholder-SurfaceHolder.Callback

发布时间:2017-11-29 所属栏目:IT计算机

一 : SurfaceHolder.Callback

一前文概要说明

首先得简单说明一下Surface与SurfaceHolder.Callback之间的联系。

Surface是android的一个重要元素,用于android画面的图形绘制。而SurfaceView是视图(View)的一个继承类,每一个SurfaceView都内嵌封装一个Surface。通过调用SurfaceHolder可以调用SurfaceView,控制图形的尺寸和大小。而SurfaceHolder是通过getholder()来取得。创立SurfaceHolder对象后,用SurfaceHolder.Callback()来回调SurfaceHolder,对SurfaceView进行控制。

单纯得用文字表述有点绕,因此下面将给出几段代码以供理解。

SurfaceHolderholder=((SurfaceView)findViewById(R.id.cameraPreview)).getHolder();

holder.addCallback(this);

holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

这样就可以通过callback()对SurfaceView进行修改。

二callback()方法介绍

callback()包括三个函数:

①surfaceCreated(SurfaceHolderholder)

当Surface第一次创建后会立即调用该函数。程序可以在该函数中做些和绘制界面相关的初始化工作,一般情况下都是在另外的线程来绘制界面,所以不要在这个函数中绘制Surface。

参数

holdersurface所创建的SurfaceHolder

②surfaceChanged(SurfaceHolderholder, int format, int width, int height)

当Surface的状态(大小和格式)发生变化的时候会调用该函数,在surfaceCreated调用后该函数至少会被调用一次。

参数

holder 更新surface的SurfaceHolder

format 新的图形格式

width 新的宽度

height 新的高度

③surfaceDestroyed()

当Surface被摧毁前会调用该函数,该函数被调用后就不能继续使用Surface了,一般在该函数中来清理使用的资源。

参数

holder所要被删除的surface的SurfaceHolder

二 : SurfaceHolder

SurfaceHolder

版本:Android 2.2 r1

结构

继承关系

public interface SurfaceHolder

android.view.SurfaceHolder

概述

抽象接口持有人显示表面。(www.61k.com]允许您控制面的大小和格式,编辑在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 新的回调接口

surfaceholder SurfaceHolder

public abstract Surface getSurface ()

直接获取Surface对象,这个Surface对象并不总是能获取的。(www.61k.com]

例如:当使用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

surfaceholder SurfaceHolder

public abstract Canvas lockCanvas (Rect dirty)

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

参数

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的窗口线程来调用

扩展:android surfaceholder / surfacechanged / surfaceholder什么意思

surfaceholder SurfaceHolder

public abstract void setType (int type)

设置该surface的类型

参数

type 该surface的内存类型

public abstract void unlockCanvasAndPost (Canvas canvas)

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

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中游戏开发的误区,不要老想着用Layout和view去实现,不要将某个游戏

中的对象做成一个组件来处理。应该尽量想着在Canvas(画布)中画出游戏戏中的背景、人物、动画等... SurfaceView提供直接访问一个可画图的界面,可以控制在界面顶部的子视图层。SurfaceView是提供给需要直接画像素而不是使用

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

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

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

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

surfaceholder SurfaceHolder

到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();

surfaceholder SurfaceHolder

}

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) {

surfaceholder SurfaceHolder

} finally {

if (c != null) {

sHolder.unlockCanvasAndPost(c);

}

}

}

}

}

}

MainActivity.Java

package com.mxgsa.drawtest;

import com.mxgsa.drawtest.view.SurfaceView1;

扩展:android surfaceholder / surfacechanged / surfaceholder什么意思

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)); }

}

扩展:android surfaceholder / surfacechanged / surfaceholder什么意思

本文标题:surfaceholder-SurfaceHolder.Callback
本文地址: http://www.61k.com/1099399.html

61阅读| 精彩专题| 最新文章| 热门文章| 苏ICP备13036349号-1