您的位置:首页 > 移动开发 > Android开发

【Android自学笔记之三】surfaceView更新线程

2011-09-29 11:15 435 查看
android中的surfaceView是做游戏的最佳选择,surfaceView中的刷新界面是主动进行刷新 :比如下面这段代码:

run方法中执行Draw()后,休眠100毫秒

public void run() {
while (mIsRunning) {
//在这里加上线程安全锁
synchronized (mSurfaceHolder) {
/**拿到当前画布 然后锁定**/
mCanvas =mSurfaceHolder.lockCanvas();
Draw();
/**绘制结束后解锁显示在屏幕上**/
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}


这样的代码看起来很规范,其实在执行draw()方法的时候,所用的时间是不可估计的,即有时候会执行1s, 也可能执行1.1s,这样的话带来的问题是显而易见的。

在贴一段科学的控游戏制循环代码,每次循环游戏主线程
在Draw()方法前后计算出Draw()方法所消耗的时间,然后在判断是否达到我们规定的刷新屏幕时间,下例是以30帧刷新一次屏幕,如果满足则继续下次循环如果不满足使用Thread.yield(); 让游戏主线程去等待 并计算当前等待时间直到等待时间满足30帧为止在继续下一次循环刷新游戏屏幕。

这里说一下Thread.yield(): 与Thread.sleep(long
millis):的区别,Thread.yield():是暂停当前正在执行的线程对象 ,并去执行其他线程。Thread.sleep(long
millis):则是使当前线程暂停参数中所指定的毫秒数然后在继续执行线程。

/**每30帧刷新一次屏幕**/
public static final int TIME_IN_FRAME = 30;
@Override
public void run() {
while (mIsRunning) {

/**取得更新游戏之前的时间**/
long startTime = System.currentTimeMillis();

/**在这里加上线程安全锁**/
synchronized (mSurfaceHolder) {
/**拿到当前画布 然后锁定**/
mCanvas =mSurfaceHolder.lockCanvas();
Draw();
/**绘制结束后解锁显示在屏幕上**/
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}

/**取得更新游戏结束的时间**/
long endTime = System.currentTimeMillis();

/**计算出游戏一次更新的毫秒数**/
int diffTime  = (int)(endTime - startTime);

/**确保每次更新时间为30帧**/
while(diffTime <=TIME_IN_FRAME) {
diffTime = (int)(System.currentTimeMillis() - startTime);
/**线程等待**/
Thread.yield();
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 游戏