SurfaceView
SurfaceView是可以实现子线程绘制的高效控件。其使用方法如下:
首先声明一个类,继承自SurfaceView并重写构造方法。
SurfaceView的生命周期方法并不直接提供出来,而是通过实现其成员变量SerfaceHolder的回调来监听,该接口要求我们重写三个方法,分别是:
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
由于其子线程绘制的特典,因此一般在surfaceCreated()方法中初始化一个子线程:
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.e("-----------","created");
a = (float) Math.random();
isRunning = true;
mThread = new Thread(this);
mThread.start();
}
然后再run方法中来完成绘制工作。
通过调用surfaceHolder.lockCanvas()来获取当前surfaceView的画布,然后绘制完成后通过调用surfaceHolder.unlockCanvasAndPost(canvas);来提交绘制,由于获取的canvas在很多情况下会为null,因此最好进行非空判断:
@Override
public void run() {
while (isRunning){
draw();
}
}
private void draw(){
try{
long start = System.currentTimeMillis();
drawBG();
rotate();
// canvas.rotate(-90f);
long dur = System.currentTimeMillis()-start;
while (dur<16){
dur = System.currentTimeMillis()-start;
Thread.yield();
}
}catch (Exception e){
e.printStackTrace();
}finally {
if(canvas!=null)
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
值得注意的是,每次调用surfaceHolder.lockCanvas()获取的画布貌似都是空的,背景啥的都得重新绘制。
surfaceView每次完成绘制所需的时间都不等,因此让线程暂停一段时间来保持帧数稳定是一种优化方案。