栏目类别:我爱答案网
[卫戍区和警备区的区别]71View和SurfaceView的区别
更新时间:2017-6-2 18:02:00 浏览量:121
篇一 : 71View和SurfaceView的区别
一、View简介
View一般在onDraw方法里面绘图,onDraw在UI主线程执行。onDraw默认只在View初始化的时候调用一遍,所以View不会自动刷新画面,一般要调用invalidate或者postInvalidate来重新执行onDraw里面的代码进行刷新画面。UI主线程一般用来渲染组件、处理组件与用户之间的交互事件,比如说按钮的点击事件、文本框的输入事件。如果你的画图任务相当繁重,那么onDraw方法里面的代码要执行好长一段时间,就可能会造成UI主线程阻塞。比如,如果在绘图的同时,用户刚好点击了某个按钮,那UI主线程会怎么处理点击事件呢?肯定是在绘图完毕后再处理点击事件,因为onDraw方法跟按钮点击事件处理都是在UI主线程内操作的。这样就给用户造成按钮点击延时处理的坏体验。
绘图原理:
主线程绘图代码和效果:
protected void onDraw(Canvas canvas)
{// 初始化画笔 Paint paint = new Paint(); // 设置抗锯齿, 文字清晰点, 不过相对比较耗性能 paint.setAntiAlias(true); // 设置画笔颜色为红色 paint.setColor(Color.RED); // 设置文字大小 paint.setTextSize(50);
// 画文字, 所画的内容都会缓存到Surface中
canvas.drawText("ITCAST", 100, 100, paint);
}
绘图效果:
既然在主线程内绘图可能会造成线程阻塞,那我们可不可以在onDraw里面开启一个新线程进行绘图呢?
在后台线程绘图代码和效果:
protected void onDraw(final Canvas canvas)
{new Thread()
{public void run()
{}
// 初始化画笔 Paint paint = new Paint(); // 设置抗锯齿, 文字清晰点, 不过相对比较耗性能 paint.setAntiAlias(true); // 设置画笔颜色为红色 paint.setColor(Color.RED); // 设置文字大小 paint.setTextSize(50); // 画文字, 所画的内容都会缓存到Surface中 canvas.drawText("ITCAST", 100, 100, paint); } }.start();
可以发现屏幕上并没有显示任何文字,说明绘图不成功,因为android只允许在UI主线程内改变UI界面,绘图完毕后渲染到屏幕上的实质就是改变UI界面。
二、SurfaceView简介
SurfaceView也可以在onDraw方法里面绘图,即直接在UI主线程绘图并渲染,因为SurfaceView是View的子类。上面已经介绍,绘图完毕后只能在UI主线程内渲染到屏幕上。为了不阻塞主线程,我们可以考虑采取这样的方案:在后台线程执行繁重的绘图任务,把所绘制的东西缓存起来;绘图完毕后,再回到UI主线程,一次性把所绘制的东西渲染到屏幕上。(本质就是后台线程绘图,UI主线程渲染)
只使用View的onDraw方法是无法实现这种方案的,而SurfaceView可以实现这种方案。 先看看SurfaceView的工作原理图:
首先,可以确定的2点:1.使用Canvas对象进行绘图;2.一定是在主线内渲染屏幕。由图可以看出,Canvas在后台线程绘制的东西先缓存到Surface中,然后让Surface回到UI主线程渲染到屏幕上。因此,要有Surface对象存在,才能够在屏幕上显示东西。顺着下面的问题来了解SurfaceView的整个工作原理。
1)Surface是什么?
Surface是SurfaceView里面的一个成员变量,它的创建和销毁过程都是自动的。Surface里面有个Canvas成员变量,将来我们就是要得到这个Canvas对象进行绘图。不过只能通过SurfaceHolder对象来控制和访问Surface。Surface的主要作用是缓存Canvas绘制的东西,并渲染到屏幕上。
2)SurfaceHolder对象怎么获取?
使用SurfaceView的getHolder()
3)在什么时候开启后台绘图线程?
最好在Surface被创建的时候,开启绘图线程。因为没有Surface,绘制再多的东西也无法渲染到屏幕上。
4)在什么时候销毁后台绘图线程?
最好在Surface被销毁的时候,销毁绘图线程。因为没有Surface,绘制再多的东西也无法渲染到屏幕上。
5) 既然要在创建Surface时开启绘图线程,在销毁Surface时销毁绘图线程。那我们怎么知道Surface在什么时候创建,什么时候销毁呢?
那就需要监听Surface的生命周期,使用SurfaceHolder对象的addCallback()来添加Surface的生命周期监听器——SurfaceHolder.Callback
Callback里面对应的方法
//Surface的大小发生改变时调用
public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){}
//Surface创建时调用,一般在这里开启绘图线程
public void surfaceCreated(SurfaceHolder holder){}
//Surface销毁时调用,一般在这里销毁绘图线程
public void surfaceDestroyed(SurfaceHolder holder) {}
再来看看如果搭建SurfaceView的游戏开发框架
1> 新建一个继承SurfaceView的类——GameView
2> 得到SurfaceHolder对象,并监听Surface的生命周期
SurfaceHolder holder;
public GameView(Context context)
{super(context);
} // 获取SurfaceHolder对象 holder = getHolder(); // 监听Surface的生命周期 holder.addCallback(this);
可以看到addCallback传的参数是this,所以GameView必须实现Callback接口 public class GameView extends SurfaceView implements Callback 实现相应的方法
/**
* Surface的大小发生改变时调用
*/
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
/**
* Surface创建时调用,一般在这里开启绘图线程
*/
public void surfaceCreated(SurfaceHolder holder) {}
/**
* Surface销毁时调用,一般在这里销毁绘图线程
*/
public void surfaceDestroyed(SurfaceHolder holder) {}
3> 开启绘图线程、销毁绘图线程
先保留一个线程成员变量
/**
* 绘图线程
*/
Thread thread;
/**
* Surface的大小发生改变时调用
*/
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}
/**
* Surface创建时调用,一般在这里开启绘图线程
*/
public void surfaceCreated(SurfaceHolder holder)
{// 开启绘图线程
thread = new Thread(this);
thread.start();
}
/**
* Surface销毁时调用,一般在这里销毁绘图线程
*/
public void surfaceDestroyed(SurfaceHolder holder)
{if (thread != null && thread.isAlive())
{try
{} } // 销毁绘图线程 thread.join(); } catch (InterruptedException e) { e.printStackTrace(); }
Thread里面传的是this,所以GameView必须实现Runnable接口
public class GameView extends SurfaceView implements Callback, Runnable
实现run方法
/**
* 这是后台绘图线程, 在这里得到Surface中Canvas进行绘图
*/
public void run() {}
4> 在run方法中尝试进行绘图
public void run()
{// 通过Holder对象获得Surface的Canvas成员变量
Canvas canvas = holder.lockCanvas();
// 初始化画笔 Paint paint = new Paint(); // 设置抗锯齿, 文字清晰点, 不过相对比较耗性能 paint.setAntiAlias(true); // 设置画笔颜色为红色 paint.setColor(Color.RED); // 设置文字大小 paint.setTextSize(50); // 画文字, 所画的内容都会缓存到Surface中 canvas.drawText("ITCAST", 100, 100, paint);
// 画完之后, 再将缓存的东西渲染到屏幕上
holder.unlockCanvasAndPost(canvas);
}
效果:
71View和SurfaceView的区别_surfacedestroyed
虽然可以画东西了,但是我们都知道,这个run方法只执行一遍,画一次就没了。我们游戏中一般都是不断地刷新屏幕,所以我们应该循环调用那段绘图代码进行刷新屏幕。我们尝试让文字动起来,就改变它的y值吧。
5> 动态刷新屏幕
先搞个循环标记
/**
* 是否正在绘图
*/
boolean running;
在开启绘图线程前改变循环标记
/**
* Surface创建时调用,一般在这里开启绘图线程
*/
public void surfaceCreated(SurfaceHolder holder)
{// 开启绘图线程
running = true;
thread = new Thread(this);
thread.start();
}
/**
* Surface销毁时调用,一般在这里销毁绘图线程
*/
public void surfaceDestroyed(SurfaceHolder holder)
{} // 改变循环标记 running = false; if (thread != null && thread.isAlive()) { try { } // 销毁绘图线程 thread.join(); } catch (InterruptedException e) { e.printStackTrace(); }
接下来循环绘图,让文字从上到下移动
int y = 0;
public void run()
{while (running)
{// 通过Holder对象获得Surface的Canvas成员变量 Canvas canvas = holder.lockCanvas(); // 先清理屏幕 canvas.drawColor(Color.BLACK); // 初始化画笔 Paint paint = new Paint(); // 设置抗锯齿, 文字清晰点, 不过相对比较耗性能 paint.setAntiAlias(true); // 设置画笔颜色为红色 paint.setColor(Color.RED); // 设置文字大小 paint.setTextSize(50); // 画文字, 所画的内容都会缓存到Surface中 canvas.drawText("ITCAST", 100, y++, paint);
// 画完之后, 再将缓存的东西渲染到屏幕上
holder.unlockCanvasAndPost(canvas);
}
}
这里需要注意的是,每次绘图前都要先清理屏幕canvas.drawColor(Color.BLACK); .
6> 改善下代码
public void run()
{// 把Canvas放在外面提高性能,不必每次都定义这个变量 Canvas canvas = null; // 将成员变量转为局部变量,也是提高性能 SurfaceHolder holder = this.holder; while(running) { // 由于涉及到多线程,这个对象最好同步 synchronized (holder)
{// 画完后最好一定释放Canvas,渲染屏幕,避免内存泄露,所以用try-finally
try
{// 通过Holder对象获得Surface的Canvas成员变量 canvas = holder.lockCanvas(); // 在这里进行绘图 render(canvas); // 画完之后可以适当暂停,没必要持续画,人的眼睛有一定的反应时间 Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } finally
{// 严谨起见,最好判断canvas是否为null,不然unlockCanvasAndPost(null)会抛异常
if (canvas != null)
{// 画完之后, 再将缓存的东西渲染到屏幕上 holder.unlockCanvasAndPost(canvas); }
}
}
}
}
int y = 0;
/**
* 绘图逻辑
*/
public void render(Canvas canvas)
{} // 先清理屏幕 canvas.drawColor(Color.BLACK); // 初始化画笔 Paint paint = new Paint(); // 设置抗锯齿, 文字清晰点, 不过相对比较耗性能 paint.setAntiAlias(true); // 设置画笔颜色为红色 paint.setColor(Color.RED); // 设置文字大小 paint.setTextSize(50); // 画文字, 所画的内容都会缓存到Surface中 canvas.drawText("ITCAST", 100, y++, paint);
这就是整个SurfaceView的游戏框架
三、View与SurfaceView对比
View:必须在UI的主线程中更新画面,用于被动更新画面
surfaceView:UI线程和子线程中都可以。在一个新启动的线程中重新绘制画面,主动更新画面
篇二 : before和ago的区别
before 和 ago 的区别
记得一点前者before可以是时间点 后者a[)go必须是时间段
ago和before这2个词都可以作“以前”解。
1、ago是副词,因此表示时间段的词语常常放在它前面,含义是从现在算起的若干时间以前,谓语动词一般使用过去时。
例如:He can ride a bike now but he couldn't a fewweeks ago.他现在会骑自行车了,可是他几个星期以前不会。
1、before可以用作介词,后接某个时间点。
例如:
Please come to my office before nine o'clock.请在九点以前到我办公室。
2、before也可以用作副词,通常表示从过去某一时刻算起的若干时间以前,谓语动词常用过去完成时。
例如:He said that he had seen the film a monthbefore. 他说他在1个月以前就看过这部电影了。
3、before可以用在现在完成时、一般过去时的句子里,不伴有具体的时间而单独使用,表示笼统、不明确的“以前”。例如:
I've read this book before.我以前看过这本书。
4、before还可以用作连词。例如:
Where did your sister study before she joined the army?你妹妹在参军以前,在哪学习?
篇三 : Androidfill_parent、wrap_content和match_parent的区别
3个属性都用来适应视图的水平或垂直大小,1个以视图的内容或尺寸为基础的布局比精确地指定视图范围更加方便。
1)fill_parent
设[]置1个构件的布局为fill_parent将强制性地使构件扩展,以填充布局单元内尽可能多的空间。这跟Windows控件的dockstyle属性大体一致。设置1个顶部布局或控件为fill_parent将强制性让它布满整个屏幕。
2) wrap_content
设置1个视图的尺寸为wrap_content将强制性地使视图扩展以显示全部内容。以TextView和ImageView控件为例,设置为wrap_content将完整显示其内部的文本和图像。布局元素将根据内容更改大小。设置1个视图的尺寸为wrap_content大体等同于设置Windows控件的Autosize属性为True。
3)match_parent
Android2.2中match_parent和fill_parent是1个意思.2个参数意思一样,match_parent更贴切,于是从2.2开始2个词都可以用。那么如果考虑低版本的使用情况你就需要用fill_parent了
篇四 : CR2032和CR2025的区别
CR2032和CR2025的区别,20表示电池的直径是20mm,32代表电池的高度为3.2mm.,25代表电池的高度为
2.5mm,CR2032额定容量为200-230mAh不等,CR2025额定容量为140-170mAh不等
CR2032:
锂二氧化锰电池,其命名是按IEC的标准命名。其中C-以锂金属为负极,以二氧化锰为正极的化学电池体系,R-表示电池的形状为圆柱形,如果是方形则F替代;20表示电池的直径是20mm,32代表电池的高度为3.2mm。标称电压为3.0V,端点电压(end point voltage)为2.0V, 额定容量为200-230mAh不等,因厂家水平而异。随着新行业的要求,也有特殊改进的电池,其容量会很不一样,主要是改进其大电流的输出能力,如应用于闪灯或RF产品的。 该电池常用于电脑主板CMOS电池上、其他记忆功能或断电保护模块、电子秤,计算器,电子辞典等产品上。
注意:
1、正确连接电池的“+”/“-”极性; 2、不同种类的电池不要在一起使用; 3、不要直接将焊料加在电池上; 4、避免电池储存在直射光、高温、高湿的环境下。
CR2032保存期
通常情况是5年寿命,如果生产厂家制造水平不高,或品质控制不好,其寿命会大大缩短。国内一线品牌的电池基本可保证这个寿命。如使用环境很理想(密封,常温,无水份等干扰)其寿命会进一步延长,可达8年,甚至10年。国内锂二氧化锰电池经过近几年的不断改进,性能已越来越接近日本电池水平,特别是国内的一线厂家,如亿纬、信湖、力佳、驰普等,当然,也有很大一部分不做品牌的小厂生产低端电池,性能品质会相差很远。
CR2025电池:
锂二氧化锰电池,其命名是按IEC的标准命名。其中C-以锂金属为负极,以二氧化锰为正极的化学电池体系,R-表示电池的形状为圆柱形,如果是方形则F替代,20代表此款电池的直径是20mm,25代表此款电池的厚度为2.5mm。标称电压为3.0V,端点电压(end point voltage)为2.0V,,额定容量为140-170mAh不等。随着新行业的要求,也有特殊改进的电池,其容量会很不一样,主要是改进其大电流的输出能力,如应用于闪灯或RF产品的。形状为纽型电池、纽扣电池、扣式电池; 该电池常用于电脑主板CMOS电池上、其他记忆功能或断电保护模块、电子秤,计算器,电子辞典等产品上。
注意:
1、正确连接电池的“+”/“-”极性; 2、不同种类的电池不要在一起使用; 3、不要直接将焊料加在电池上; 4、避免电池储存在直射光、高温、高湿的环境下。
CR2025保存期
通常情况是5年寿命,如果生产厂家制造水平不高,或品质控制不好,其寿命会大大缩短。国内一线品牌的电池基本可保证这个寿命。如使用环境很理想(密封,常温,无水份等干扰)其寿命会进一步延长,可达8年,甚至10年。国内锂二氧化锰电池经过近几年的不断改进,性能已越来越接近日本电池水平,特别是国内的一线厂家,如亿纬、信湖、力佳、驰普等,当然,也有很大一部分不做品牌的小厂生产低端电池,性能品质会相差很远。
篇五 : YUVYCbCrYPbPr区别
Y'UV是PAL系统使用的1种颜色空间,与NTSC系统中的Y'IQ作用相似。Y'PbPr指模拟分量信号或模拟分量接口,P是Parallel的缩写,意为并行。而Y'CbCr指的是数字分量信号,C是Chroma的缩写,意为色度。实际上,CbCr这种表示方式早于PbPr。但长久以来,这几个名称的使用有些混乱,很多文章常使用YUV指代Y'CbCr或Y'PbPr,Y'CbCr与Y'PbPr的使用也常常混淆。
这里要说明的是,由于网易博客系统的原因,CbCr与PbPr中的B与R都应为大写形式。Y'及以下的R'G'B'右上角的一撇,是表示经过非线性校正后的分量,以区别线性分量。
以摄像机等信号源为例,视频信号流程大致如下。RGB经伽马校正形成R'G'B',而后经过矩阵变换得到Y'/B'-Y'/R'-Y',而后根据需要进行处理,因此B'-Y'与R'-Y'一般不直接使用。
UV是由B'-Y'与R'-Y'限幅而来的,限幅的目的是防止色域越限,同时确保编码后的复合电视信号电平在VHF/UHF电视发射机的要求范围内。这里补充一下,如果是摄像机等视频设备直接输出的信号,一般不会出现色域方面的问题,但随着计算机越来越多的参与到节目制作过程中,加之多种色域间的转换,可能会造成色域越限。进入PAL编码器之前,UV还要经过滤波,利用人类视觉对色度信息的分辨能力低于对亮度信息的分辨能力的特性,以节省带宽。因此,UV可以看作是PAL系统的专有符号。
Y'PbPr是为了满足高质量视频传输而设计的色彩分量形式及接口形式,采用并行传输的方式。PbPr也是由B'-Y'及R'-Y'经过限幅得到的,目前,这种接口多见于模拟分量录像机、高清摄[)录一体机及DVD播放机等。模拟分量传输绕过了PAL编码与解码,减轻了亮/色串扰等编解码对图像的损失,但传输距离受到限制。在同步电平规则上,Y'PbPr大致分为三种,SMPTE曾试图统一模拟分量接口,但以失败告终。
Y'CbCr是数字电视标准化时,为了兼容亮度、色差这种色彩编码方式而采用的1种类似于Y'PbPr的分量形式。CbCr是对B'-Y'与R'-Y'进行限幅及数字化得到的,因此CbCr是数字色差分量。一般来说,国际认可的演播室数字分量编码标准皆使用4:2:2色度亚取样,即B'-Y'及R'-Y'的取样频率各为Y'的一半。除4:2:2外,常见的亚取样方式还有4:1:1、4:2:0。亚取样也可以看作是1种滤波,只不过是数字滤波。
无论Y'UV还是Y'CbCr或Y'CbCr,其实都是为了兼容黑白电视系统而设计的。展望未来,高质量节目制作或数字电影,有可能直接采用R'G'B'分量,由于无法进行色度滤波,因此只能采用4:4:4即全带宽传输及记录。
和rgb之间换算公式的差异
yuv<-->rgb
Y'= 0.299*R' + 0.587*G' + 0.114*B'
U'= -0.147*R' - 0.289*G' + 0.436*B' = 0.492*(B'- Y')
V'= 0.615*R' - 0.515*G' - 0.100*B' = 0.877*(R'- Y')
R' = Y' + 1.140*V'
G' = Y' - 0.394*U' - 0.581*V'
B' = Y' + 2.032*U'
yCbCr<-->rgb
Y’ = 0.257*R' + 0.504*G' + 0.098*B' + 16
Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128
Cr' = 0.439*R' - 0.368*G' - 0.071*B' + 128
R' = 1.164*(Y’-16) + 1.596*(Cr'-128)
G' = 1.164*(Y’-16) - 0.813*(Cr'-128) - 0.392*(Cb'-128)
B' = 1.164*(Y’-16) + 2.017*(Cb'-128)
Note: 上面各个符号都带了一撇,表示该符号在原值基础上进行了gamma correction
来源上的差异
yuv色彩模型来源于rgb模 型,
该模型的特点是将亮度和色度分离开,从而适合于图像处理领域。
应用:basic color model used in analogue color TV broadcasting.
YCbCr模型来源于yuv模 型。YCbCr is a scaled and offset version of the YUVcolor space.
应用:数字视频,ITU-R BT.601 recommendation
上一篇:[重庆高考录取查询入口]2015重庆高考录取通知书EMS查询入口及步骤
下一篇:[nero如何刻录cd光盘]如何用nero将APE刻录成CD