**
1.surfaceView与View的区别
**
View通过刷新来重绘视图,Android系统通过发出VSYNC信号来进行屏幕的重绘,刷新时间间隔为16ms。如果16ms内View完成了需要执行的所有操作,不会在视觉上出现卡顿的感觉,反之,则会出现。
surfaceView的出现就是解决这个问题。
surefaceView和Viewde 区别:
(1)View主要适用于主动更新的情况下,而SurfaceView主要适用于被动更新,例如频繁的刷新。
(2)View在主线程中对画面进行刷新,而surface通过一个子线程来进行页面的刷新。
(3)View在绘图时没有使用双缓冲机制,而SurfaceView在底层实现机制中就已经实现双缓冲机制
双缓冲机制:
参见:http://www.yafeilinux.com/?p=73
不用画布,直接在窗口上进行绘图叫做无缓冲绘图。用了一个画布,将所有内容都先画到画布上,在整体绘制到窗口上,就该叫做单缓冲绘图,那个画布就是一个缓冲区。用了两个画布,一个进行临时的绘图,一个进行最终的绘图,这样就叫做双缓冲绘图。
surfaceView自身实现了双缓冲,而View没有。其实view你也可以自己实现,但是实现的结构不如surfaceView好。
surfaceView通过 surfaceHolder.lockCanvas 锁定画布,实现下一张图片的绘制,再通过另外的线程刷新界面,绘制图片。
view则是直接在ondraw里绘制图片,刷新界面。其实view也可以实现双缓冲机制,你可以在另个出ondraw的方法中绘制下一张bitmap
,就实现了view的双缓冲。
为什么动态绘图surfaceView要比View好?
因为View是在UI主线程中进行绘制的,绘制时会阻塞主线程,如果ontouch事件又处理的比较多的话会导致界面卡。而surfaceView是另开了一个线程绘制的,再加上双缓冲机制,所以要高效。不会卡。其实现在一般实现view的时候一般都会在其他出先生成bitmap在给ondraw去画,所以双缓冲的作用不是那么明显了(个人认为)。
**
2.SurfaceView的使用
**
(1)创建SurfaceView
创建自定义的SurfaceView继承自SurfaceView,并实现两个接口-SurfaceHolder.CallBack和Runable
public class SimpleDraw extends SurfaceView
implements SurfaceHolder.Callback, Runnable {
实现接口的方法:
分别对应SurfaceView的创建、改变和销毁过程。
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing = true;
new Thread(this).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mIsDrawing = false;
}
(2)初始化SurfaceView
在自定义SurfaceView的构造方法中,需要对SurfaceView进行初始化。
定义以下三个成员变量
private SurfaceHolder mHolder;
//用于绘图的Canvas
private Canvas mCanvas;
//子线程标志位
private boolean mIsDrawing;
初始化SurfaceView
mHolder = getHolder();
mHolder.addCallback(this);
(3)使用SurfaceView
通过SurfaceHolder对象的lockCanvas()方法,就可以获取当前的Canvas绘图对象。这里获取的Canvas对象还是继续上次的Canvas对象,而不是一个新的对象。需要擦出,则可以在绘制前调用drawColor()方法来进行清屏操作。
整个SurfaceView的模版代码如下
package com.imooc.surfaceviewtest;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class SurfaceViewTemplate extends SurfaceView
implements SurfaceHolder.Callback, Runnable {
// SurfaceHolder
private SurfaceHolder mHolder;
// 用于绘图的Canvas
private Canvas mCanvas;
// 子线程标志位
private boolean mIsDrawing;
public SurfaceViewTemplate(Context context) {
super(context);
initView();
}
public SurfaceViewTemplate(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public SurfaceViewTemplate(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView();
}
private void initView() {
mHolder = getHolder();
mHolder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
//mHolder.setFormat(PixelFormat.OPAQUE);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing = true;
new Thread(this).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mIsDrawing = false;
}
@Override
public void run() {
while (mIsDrawing) {
draw();
}
}
private void draw() {
try {
mCanvas = mHolder.lockCanvas();
// draw sth
} catch (Exception e) {
} finally {
if (mCanvas != null)
mHolder.unlockCanvasAndPost(mCanvas);
}
}
}
注意将mHolder.unlockCanvasAndPost(mCanvas)方法放在finally代码块中,保证每次内容提交。、
SurfaceView实例