zoukankan      html  css  js  c++  java
  • SurfaceView的使用

    1.定义

    SurfaceView继承自View,内嵌了一个专门用于绘制的Surface,Surfaceview不仅可以控制这个Surface的格式和尺寸,还能控制其绘制位置;因为可以直接从内存或者DMA等硬件接口取得图像数据,所以是个非常重要的绘图容器。

    2.使用

    首先要知道SurfaceView的一些特性,然后根据特性决定用途;

    * SurfaceView 单位时间内完成界面的大量多次更新

    * 双缓冲机制 :

    * A线程----更新ui -----后台计算---更新ui

    * B线程----后台计算----更新ui ---后台计算

    * 可以在子线程更新ui

    在主线程之外的线程中向屏幕绘图上,这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。在游戏开发中多用到SurfaceView,游戏中的背景、人物、动画等等尽量在画布canvas中画出。

    surfaceView.getHolder().addCallback(new Callback() {
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            //surfaceView被销毁时调用
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            //surfaceView被创建时调用
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height) {
            //surfaceView发生变化时调用
        }
    });

    首先继承SurfaceView并实现SurfaceHolder.Callback接口
    使用接口的原因:因为使用SurfaceView 有一个原则,所有的绘图工作必须得在Surface 被创建之后才能开始(。基本上我们可以把它当作显存的一个映射,写入到Surface 的内容可以被直接复制到显存从而显示出来,这使得显示速度会非常快),而在Surface 被销毁之前必须结束。所以Callback 中的surfaceCreated 和surfaceDestroyed 就成了绘图处理代码的边界。

    3.实例

    sv.getHolder().addCallback(new Callback() {
    
                    @Override
                    public void surfaceDestroyed(SurfaceHolder holder) {
                        System.out.println("surface被销毁了");
                        flag = false;
                    }
    
                    @Override
                    public void surfaceCreated(SurfaceHolder holder) {
                        System.out.println("surface创建了");
                        flag = true;
                        new Thread(){
                            public void run() {
                                for(int i = 0;i<100;i++){
                                    if(!flag){
                                        return ;
                                    }
                                //界面里面内容显示的控制器
                                    SurfaceHolder holder = sv.getHolder();
                                    Canvas  canvas = holder.lockCanvas();
                                    canvas.drawColor(Color.BLACK);
                                    int radius = 5+i;
                                    Paint paint = new Paint();
                                    paint.setColor(Color.RED);
                                    canvas.drawCircle(250, 250, radius, paint);
                                    holder.unlockCanvasAndPost(canvas);
                                    SystemClock.sleep(100);
                                }
                            };
                        }.start();
                    }
    
                    @Override
                    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                            int height) {
                        System.out.println("surface大小发生了变化");
                    }
                });

       上述代码实现的内容是canvas动态地画一个半径逐渐增大的圆形成的动画;

       整个过程:继承SurfaceView并实现SurfaceHolder.Callback接口 ----> SurfaceView.getHolder()获得SurfaceHolder对象 ---->SurfaceHolder.addCallback(callback)添加回调函数----   >SurfaceHolder.lockCanvas()获得Canvas对象并锁定画布----> Canvas绘画 ---->SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。

     

       下面贴出SurfaceView实现视频播放器的实例:

        

                sv = (SurfaceView) findViewById(R.id.sv);
                sp = getSharedPreferences("config", MODE_PRIVATE);
    
                sv.getHolder().addCallback(new Callback() {
    
                    @Override
                    public void surfaceDestroyed(SurfaceHolder holder) {
                        System.out.println("surface被销毁");
                        if(mediaPlayer!=null){
                            int position = mediaPlayer.getCurrentPosition();
                            Editor editor  = sp.edit();
                            editor.putInt("position", position);
                            editor.commit();
                            mediaPlayer.stop();
                            mediaPlayer.release();
                        }
                    }
    
                    @Override
                    public void surfaceCreated(SurfaceHolder holder) {
                        System.out.println("surface被创建");
                        try {
                            mediaPlayer = new MediaPlayer();
                            mediaPlayer.setDataSource("/mnt/sdcard/oppo.3gp");
                            mediaPlayer.prepare();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        //指定多媒体的内容实在holder里面显示
                        mediaPlayer.setDisplay(holder);
                        mediaPlayer.start();
                        mediaPlayer.seekTo(sp.getInt("position", 0));
                    }
    
                    @Override
                    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                            int height) {
                    }
                });

    4.小结

       SurfaceView的使用远不止于此,它比想象的更加强大,后面会涉及到SurfaceView的进阶使用.

  • 相关阅读:
    【逻辑漏洞技巧拓展】————4、逻辑漏洞之支付漏洞
    【逻辑漏洞技巧拓展】————3、逻辑漏洞之密码重置
    【逻辑漏洞技巧拓展】————2、Web安全测试中常见逻辑漏洞解析(实战篇)
    【逻辑漏洞技巧拓展】————1、逻辑至上之各种酷炫姿势
    【文件上传/解析技巧拓展】————4、文件上传总结
    【文件上传/解析技巧拓展】————3、服务器解析漏洞
    【文件上传/解析技巧拓展】————2、文件上传漏洞(绕过姿势)
    window 杀进程
    URL的三部分
    基本的浏览器连接处理步骤
  • 原文地址:https://www.cnblogs.com/fuyaozhishang/p/6855071.html
Copyright © 2011-2022 走看看