性能优化 – 优化SurfaceView的线程调用
目录
SurfaceView的基本用法
SurfaceView是一个适用于频繁的刷新布局的View,可以在非主线程中刷新View,其基本用法如下
创建实例对象
SurfaceView mSurfaceView = new SurfaceView(this);
setContentView(mSurfaceView);
添加SurfaceHolder.Callback
mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
在Surface创建改变和销毁时会调用此回调
一般会在surfaceCreated
方法中启用一个线程,然后借用这个线程来刷新View
mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
private boolean destroy = false;
@Override
public void surfaceCreated(final SurfaceHolder holder) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (!destroy) {
Canvas canvas = holder.lockCanvas();
onDraw(canvas);
holder.unlockCanvasAndPost(canvas);
}
}
});
thread.start();
}
private void onDraw(Canvas canvas) {
canvas.drawColor(Color.GREEN);
//.......................在此做对View的绘制操作
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
destroy = true;
}
});
首先借用new Thread
创建一个线程,然后用一个变量destroy
来标记SurfaceView的状态,借助destroy
来控制线程的启停.
然后在线程中通过holder.lockCanvas()
获得画布对象canvas
,通过holder.unlockCanvasAndPost(canvas)
释放和发送canvas
对象来刷新布局.
值得注意的是用以上方法获得的Canvas对象是之前留下来的,所以如果没有需要保留上次绘制的情况下,需要调用canvas.drawColor()
来执行一次清屏操作.
问题
基本用法介绍完了,那么思考个问题,上面创建了一个线程,几乎是死循环,就算没有新视图的刷新,线程还是一直在运行,这样是对系统资源的一种浪费,那么该如何优化线程的使用呢?
加延时吗?
加延时的化,Android屏幕的刷新时间是16ms,如果超过这个时间,便会有卡顿的感觉,也就是说加延时的话最多在每次循环里加16ms.
每次延时16ms,在一般情况下有点杯水车薪的感觉,然后有时候也可能有