Android图形系统之Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback开发实例

摘要:
当SurfaceView窗口可见时,将创建曲面。当“SurfaceView”窗口隐藏时,曲面将被破坏。应在主线程中调用所有SurfaceViews和SurfaceHolders回调方法,以确保渲染过程访问的变量的同步。必须确保渲染过程仅在有效时才能访问曲面。SurfaceView和Surface之间的连接是,Surface用于管理显示的数据,包括存储在其中的数据交换。与直接控制SurfaceView修改曲面不同,使用SurfaceHolder修改曲面时,需要注意lockCanvas()和Callback。surfaceCreated()。SurfaceHolder用于控制表面处理的几种方法。

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

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

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

通过SurfaceHolder这个接口去访问Surface,而执行getHolder()方法可以得到SurfaceHolder接口。当SurfaceView的窗口可见时,Surface就会被创建,当SurfaceView窗口隐藏时,Surface就会被销毁。

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

  • 所有SurfaceView 和 SurfaceHolder.Callback的方法都应该在主线程(UI线程)里面调用,应该要确保渲染进程所访问变量的同步性。
  • 必须确保只有当Surface有效的时候,(也就是当Surface的生命周期在SurfaceHolder.Callback.surfaceCreated() 和SurfaceHolder.Callback.surfaceDestroyed()之间)才能让渲染进程访问。

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

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.// 结束锁定画图,并提交改变

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

  1. public abstract voidsurfaceChanged(SurfaceHolder holder, int format, int width, int height)

holder  The SurfaceHolder whose surface has changed.

format  The new PixelFormat of the surface.

width   The new width of the surface.

height  The new height of the surfa     //surface发生改变时被调用

  2. public abstract voidsurfaceCreated(SurfaceHolder holder)

Parameters     holder    The SurfaceHolder whose surface is being created

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

  3. public abstract voidsurfaceDestroyed(SurfaceHolder holder)

Parameters     holder    The SurfaceHolder whose surface is being destroyed. 

//销毁时被调用,一般在这个方法里将渲染的线程停止。

Demo:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this));
    }

    class MyView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
        SurfaceHolder holder = null;
        Paint paint;

        public MyView(Context context) {
            super(context);
            holder = getHolder();
            holder.addCallback(this);
            paint = new Paint(Paint.ANTI_ALIAS_FLAG);    // 创建画笔
            paint.setColor(Color.RED);                    // 设置画笔颜色
            this.setFocusable(true);
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            Thread t = new Thread(this);
            t.start();
        }
        
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,    int height) {
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            isRunning = false;
        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas = holder.lockCanvas();
            canvas.drawColor(Color.BLACK);
            canvas.drawCircle(x, y, 10, paint);
            holder.unlockCanvasAndPost(canvas);
        }

        private void paint(Paint paint) {
            Canvas canvas = holder.lockCanvas();    // 锁定画布,得到Canvas对象
            canvas.drawColor(Color.WHITE);            // 设定Canvas对象的背景颜色
            canvas.drawCircle(x, y, 10, paint);        // 在画布上画圆
            holder.unlockCanvasAndPost(canvas);        // 解除锁定,并提交修改内容,更新屏幕
        }
        boolean isRunning = true;

        @Override
        public void run() {
            while (isRunning) {
                // onDraw(null);
                paint(paint);
                move();
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        private int x, y;
        private void move() {
            x += 2;
            y += 2;
        }
    }
}

免责声明:文章转载自《Android图形系统之Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback开发实例》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇HTTP Bearer认证及JWT的使用eclipse 创建Maven 架构的dynamic web project 问题解决汇总下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

canvas 图片拖拽旋转之一——坐标转换translate

引言 对canvas中绘制的图片进行旋转操作,需要使用ctx.translate变换坐标系,将图片旋转的基点设为坐标系的原点,然后ctx.rotate旋转。 这个时候,因为canvas坐标系发生了旋转,而视觉感受上的坐标以及鼠标事件中的坐标都是旋转之前的屏幕坐标系。再根据鼠标的移动去控制canvas中的图片时,就会出现问题。 用A坐标系中的偏移来控制B坐标...

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

是在2012年的除夕之夜仓促完成,后来很多人指出了一些问题,琐事缠身一直没有进行升级。后来随着我自己的使用,越来越发现不出个升级版的demo是不行了。有时候就连我自己用这个demo测一些性能、功能点,用着都不顺手。当初代码是在linux下写的,弄到windows里下全是乱码。还要自己改几分钟才能改好。另外,很多人说不能正常预览,原因是我在布局里把Surfa...

js 回调函数

回调函数定义: A callback is a function that is passed as an argument to another function and is executed after its parent function has completed。 一个回调是一个函数被传递一个参数到另外一个函数,被执行在主函数完成后 n...

将某个div内容保存成图片,使用html2canvas截图方法(高清图并解决图片跨域问题)

首先附上html2canvas的CDN地址:http://www.bootcdn.cn/html2canvas/ ; 此方法可截取整个div的内容,包括不可视区域,并且可以实现跨域图片截图。之前看了很多关于html2canvas插件图片跨域的解决办法,大部分的答复是在服务器端配置,之后将useCORS属性设置为true,但是如果图片是保存在别人家的服务器上...

WebSocket实战

前言 互联网发展到现在,早已超越了原始的初衷,人类从来没有像现在这样依赖过他;也正是这种依赖,促进了互联网技术的飞速发展。而终端设备的创新与发展,更加速了互联网的进化; HTTP/1.1规范发布于1999年,同年12月24日,HTML4.01规范发布;尽管已到2012年,但HTML4.01仍是主流;虽然 HTML5的草案已出现了好几个年头,但转正日期,遥...

ExtJS 4.2 教程-06:服务器代理(proxy)

在上一节我们介绍了客户端的几种代理,本节的主要内容是介绍如何使用服务器端代理,将重点介绍AjaxProxy,这是我们最常用的代理方式。 Ajax web应用程序开发过程中,与服务器端交互的技术最常用的就是Ajax了。Ajax 是使用Javascript创建一个HttpRequest,采用异步的方式从服务器获取数据。我们先看一个简单的示例: Ext.onR...