Android之SurfaceView学习

首先我们先来看下官方API对SurfaceView的介绍

SurfaceView的API介绍

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 calling getHolder().

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

?All SurfaceView and SurfaceHolder.Callback methods will be called from the thread running the SurfaceView's window (typically the main thread of the application). They thus need to correctly synchronize with any state that is also touched by the drawing thread. 

?You must ensure that the drawing thread only touches the underlying Surface while it is valid -- between SurfaceHolder.Callback.surfaceCreated() and SurfaceHolder.Callback.surfaceDestroyed(). 

对应的中文翻译

SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置。

        surface是纵深排序(Z-ordered)的,这表明它总在自己所在窗口的后面。surfaceview提供了一个可见区域,只有在这个可见区域内 的surface部分内容才可见,可见区域外的部分不可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者 surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,如果surface上面 有透明控件,那么它的每次变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。

        你可以通过SurfaceHolder接口访问这个surface,getHolder()方法可以得到这个接口。

        surfaceview变得可见时,surface被创建;surfaceview隐藏前,surface被销毁。这样能节省资源。如果你要查看 surface被创建和销毁的时机,可以重载surfaceCreated(SurfaceHolder)和 surfaceDestroyed(SurfaceHolder)。

        surfaceview的核心在于提供了两个线程:UI线程和渲染线程。这里应注意:

        1> 所有SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用,一般来说就是应用程序主线程。渲染线程所要访问的各种变量应该作同步处理。

        2> 由于surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之间有效,所以要确保渲染线程访问的是合法有效的surface。

接下来呢,说说自己对它的理解

1、定义

可以直接从内存或者DMA等硬件接口取得图像数据,是个非常重要的绘图容器。

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

2、实现

首先继承SurfaceView并实现SurfaceHolder.Callback接口

使用接口的原因:因为使用SurfaceView 有一个原则,所有的绘图工作必须得在Surface 被创建之后才能开始(Surface—表面,这个概念在 图形编程中常常被提到。基本上我们可以把它当作显存的一个映射,写入到Surface 的内容

                      可以被直接复制到显存从而显示出来,这使得显示速度会非常快),而在Surface 被销毁之前必须结束。所以Callback 中的surfaceCreated 和surfaceDestroyed 就成了绘图处理代码的边界。

需要重写的方法

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

 //在surface的大小发生改变时激发

 (2)public void surfaceCreated(SurfaceHolder holder){}

 //在创建时激发,一般在这里调用画图的线程。

 (3)public void surfaceDestroyed(SurfaceHolder holder) {}

 //销毁时激发,一般在这里将画图的线程停止、释放。

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



3、SurfaceHolder

这里用到了一个类SurfaceHolder,可以把它当成surface的控制器,用来操纵surface。处理它的Canvas上画的效果和动画,控制表面,大小,像素等。

几个需要注意的方法:

(1)、abstract void addCallback(SurfaceHolder.Callback callback);

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

(2)、abstract Canvas lockCanvas();

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

(3)、abstract Canvas lockCanvas(Rect dirty);

// 锁定画布的某个区域进行画图等..因为画完图后,会调用下面的unlockCanvasAndPost来改变显示内容。

// 相对部分内存要求比较高的游戏来说,可以不用重画dirty外的其它区域的像素,可以提高速度。

(4)、abstract void unlockCanvasAndPost(Canvas canvas);

// 结束锁定画图,并提交改变。

4、实例

这里的例子实现了一个矩形和一个计时器

View Code

1 packagexl.test;
2 
3 importandroid.app.Activity;
4 importandroid.content.Context;
5 importandroid.graphics.Canvas;
6 importandroid.graphics.Color;
7 importandroid.graphics.Paint;
8 importandroid.graphics.Rect;
9 importandroid.os.Bundle;
10 importandroid.view.SurfaceHolder;
11 importandroid.view.SurfaceView;
12 
13 publicclassViewTestextendsActivity {
14 /**Called when the activity is first created.*/
15 @Override
16 publicvoidonCreate(Bundle savedInstanceState) {
17 super.onCreate(savedInstanceState);
18 setContentView(newMyView(this));
19 }
20 //视图内部类
21 classMyViewextendsSurfaceViewimplementsSurfaceHolder.Callback
22 {
23 privateSurfaceHolder holder;
24 privateMyThread myThread; 
25 publicMyView(Context context) {
26 super(context);
27 //TODO Auto-generated constructor stub
28 holder=this.getHolder();
29 holder.addCallback(this);
30 myThread=newMyThread(holder);//创建一个绘图线程
31 }
32 
33 @Override
34 publicvoidsurfaceChanged(SurfaceHolder holder,intformat,intwidth,
35 intheight) {
36 //TODO Auto-generated method stub
37 
38 }
39 
40 @Override
41 publicvoidsurfaceCreated(SurfaceHolder holder) {
42 //TODO Auto-generated method stub
43 myThread.isRun=true;
44 myThread.start();
45 }
46 
47 @Override
48 publicvoidsurfaceDestroyed(SurfaceHolder holder) {
49 //TODO Auto-generated method stub
50 myThread.isRun=false;
51 }
52 
53 }
54 //线程内部类
55 classMyThreadextendsThread
56 {
57 privateSurfaceHolder holder;
58 publicbooleanisRun ;
59 publicMyThread(SurfaceHolder holder)
60 {
61 this.holder=holder; 
62 isRun=true;
63 }
64 @Override
65 publicvoidrun()
66 {
67 intcount=0;
68 while(isRun)
69 {
70 Canvas c=null;
71 try
72 {
73 synchronized(holder)
74 {
75 c=holder.lockCanvas();//锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。
76 c.drawColor(Color.BLACK);//设置画布背景颜色
77 Paint p=newPaint();//创建画笔
78 p.setColor(Color.WHITE);
79 Rect r=newRect(100,50,300,250);
80 c.drawRect(r, p);
81 c.drawText("这是第"+(count++)+"",100,310, p);
82 Thread.sleep(1000);//睡眠时间为1秒
83 }
84 }
85 catch(Exception e) {
86 //TODO: handle exception
87 e.printStackTrace();
88 }
89 finally
90 {
91 if(c!=null)
92 {
93 holder.unlockCanvasAndPost(c);//结束锁定画图,并提交改变。
94 
95 }
96 }
97 }
98 }
99 }
100 }

Android Camera之SurfaceView学习相关推荐

  1. android自定义camera预览区域,android camera摄像surfaceview预览界面特定区域(该区域可移动)...

    1.自定义一个imageview用来设定surfaceview上的特定区域. public class DrawImageView extends ImageView { private Paint ...

  2. 我心依旧之Android Camera模块FW/HAL3探学序

    前沿: 目前对于Android Camera软硬件技术发展的主流方向是高像素.高帧率.多摄像头.超强的ISP以及各种视频图形处理算法等等.当前主流的Android系统中较为常见的Camera模块还均是 ...

  3. android摄像头预览功能,android通过camera和surfaceview选择摄像头并即时预览

    在使用android设备的摄像头的时候我们有两种选择: 1.调用intent方法使用摄像头 2.通过camera类使用摄像头 第一种方法非常方便,不过需要跳到新的activity中,这样的用户体验并不 ...

  4. Camera HAL3学习: Android Camera System

    Android Camera硬件抽象层(HAL,Hardware Abstraction Layer)主要用于把底层camera drive与硬件和位于android.hardware中的framew ...

  5. 基于Mtk平台的android camera hal3学习

     框架 Android Camera硬件抽象层(HAL,Hardware Abstraction Layer)主要用于把底层camera driver的实现接口进行封装,再经过算法处理,提供接口给f ...

  6. 一牛网:Android camera驱动培训班,不可错过的学习机会

    Android camera驱动培训: 学员要求: 1.要有C语言基础 2.有android.linux.或其他嵌入式系统基础 3.对这块有强烈兴趣者. 师资团队: 主讲:一牛网_Jacky 老师(驱 ...

  7. Android Camera 编程从入门到精通

    一.前言 想通过一篇文章就让我们精通 Android 的 Camera 那肯定是不可能的事情.但通过对 Android 中相机拍照的所有的方式的梳理和理解,包括直接调起相机拍照,Camera API ...

  8. Android Camera数据流分析全程记录(overlay方式一)

     Android Camera数据流分析全程记录(overlay方式) 这里为什么要研究overlay方式呢?android camera需要driver和app层需要有大量数据需要传输,如果使用非o ...

  9. Android Camera:从零开发一款相机APP

    从零开发一款相机APP Day 1: 前言 一.Android Camera开发前景: 1)camera相关应用的领域 2)相关岗位介绍: 3)市场招聘介绍: 4)发展前景介绍: 二.学习这门课的重要 ...

最新文章

  1. python—unittest—数据驱动详细讲解(ddt)
  2. nginx重新加载php,如何使用nginx启动、停止和重新加载
  3. Linux面试题100道
  4. 关于对玩过的游戏的想法汇总
  5. 计算机网络技术-----==一些东西
  6. ubuntu16:查看磁盘空间大小,查看每个用户的占用空间情况
  7. Android自定义控件之TextView
  8. Java笔记(day12)
  9. 2021年度图学会第十七期全国BIM等级考试一级真题
  10. 线性线性混合效应模型及R语言实现
  11. matlab学习技巧之semilogx和semilogy函数
  12. 摄影构图的几种基本方法
  13. [人工智能-深度学习-72]:卷积神经网络 - 空间金字塔池化SPP-Net网络与Pytorch代码实现
  14. IIS站点出现503错误。
  15. jQuery DOM操作 实现本地表格查询
  16. python dataframe isin,使用多个条件获取新的数据帧pd.Dataframe.isin()
  17. 计算机组成原理诺,计算机组成原理与系统结构 第8章 计算机系统结构.ppt
  18. 七十八、Kettle的几个使用案例
  19. java 中加载图片
  20. c语言51单片机脉冲计数检测,51单片机计数测速(外部脉冲频率)proteus仿真加源码...

热门文章

  1. Microsoft Dynamics CRM 2013 的权限管理与分配 (二)
  2. python查询注册表子项是否存在并操作
  3. 讨论CGContextDrawImage
  4. ASP.NET MVC2用户界面的巨大改变
  5. 看上冰岛的域名con.is
  6. VBNET常用字符串常量
  7. C#利用正则表达式实现字符串搜索
  8. win10安装pytorch很慢,如何解决?
  9. java访问本地文件_详解Java读取本地文件并显示在JSP文件中
  10. C语言scanf输入a3,【C语言】04 printf和scanf函数