Android 多次更新SurfaceView的更好方法?
我正在使用一个Android 多次更新SurfaceView的更好方法?,android,performance,Android,Performance,我正在使用一个SurfaceView,我必须尽快更新它。因为onDraw方法不是自动调用的,所以我必须显式调用。所以我的第一次尝试是在线程上,但是我得到了一些延迟。有更好的办法吗?如果有更好的解决办法,你能给我解释一下吗?我是Android世界的新手 到目前为止我拥有的 public void run() { while(running){ Canvas c = null; try { c = view.getHolder().l
SurfaceView
,我必须尽快更新它。因为onDraw方法不是自动调用的,所以我必须显式调用。所以我的第一次尝试是在线程上,但是我得到了一些延迟。有更好的办法吗?如果有更好的解决办法,你能给我解释一下吗?我是Android世界的新手
到目前为止我拥有的
public void run() {
while(running){
Canvas c = null;
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.onDraw(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
}
}
以下是我的代码,我将其用作渲染线程。fps根据帧进行更新。我通常以每秒30帧的速度运行游戏。 (有一些代码您不需要,但我相信您将能够找到您正在寻找的片段。)
public类RenderView扩展了SurfaceView实现了Runnable{
游戏;
位图游戏屏幕;
线程循环;
表面焊钳;
布尔运算;
int睡眠时间;
int numberofframesskiped;
int maxFrameSkips;
漫长的开端;
长时间;
时间长;
积分差分时间;
整数帧周期;
画布帧缓冲区;
整数帧计数;
公共渲染视图(int fps、int maxFrameSkips){
超级(游戏);
this.gameScreen=gameScreen;
this.holder=getHolder();
此.framePeriod=1000/fps;
this.maxFrameSkips=maxFrameSkips;
lastTime=System.currentTimeMillis();
beginTime=System.currentTimeMillis();
}
@凌驾
公开募捐{
while(running==true){
if(holder.getSurface().isValid()){
beginTime=System.currentTimeMillis();
//在这里调用您的更新方法
//在这里渲染
frameBuffer=holder.lockCanvas();
这个;
支架。解锁CanvasandPost(帧缓冲区);
//每秒帧数
frameCount++;
如果(lastTime+10000){
试一试{
睡眠(睡眠时间);
}捕获(中断异常异常){
异常。printStackTrace();
}
}
否则{
while(sleepTime<0&&numberOfFramesSkipped
我建议你看看这个链接或者
或者有一些重复的LOC,而且非常复杂。你能简化它吗?更新了代码(试图减少它)并添加了一些有用的链接。
public class RenderView extends SurfaceView implements Runnable {
Game game;
Bitmap gameScreen;
Thread gameloop;
SurfaceHolder holder;
boolean running;
int sleepTime;
int numberOfFramesSkipped;
int maxFrameSkips;
long beginTime;
long endTime;
long lastTime;
int differenceTime;
int framePeriod;
Canvas frameBuffer;
int frameCount;
public RenderView(int fps, int maxFrameSkips) {
super(game);
this.gameScreen = gameScreen;
this.holder = getHolder();
this.framePeriod = 1000/fps;
this.maxFrameSkips = maxFrameSkips;
lastTime = System.currentTimeMillis();
beginTime = System.currentTimeMillis();
}
@Override
public void run() {
while(running == true) {
if(holder.getSurface().isValid()) {
beginTime = System.currentTimeMillis();
// call your update method here
// render here
frameBuffer = holder.lockCanvas();
this.onDraw();
holder.unlockCanvasAndPost(frameBuffer);
// Frame Per Second Count
frameCount++;
if(lastTime + 1000 < System.currentTimeMillis()) {
lastTime = System.currentTimeMillis();
frameCount = 0;
}
endTime = System.currentTimeMillis();;
differenceTime = (int) (endTime - beginTime);
sleepTime = (int) (framePeriod - differenceTime);
if(sleepTime > 0) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
else {
while(sleepTime < 0 && numberOfFramesSkipped < this.maxFrameSkips) {
// Call your update method here
sleepTime += framePeriod;
numberOfFramesSkipped++;
}
}
}
}
}
private void renderFrameBuffer() {
// Update the current virtual screen image
game.getCurrentScreen().render();
// Render the current virtual screen to the real phone screen
frameBuffer = holder.lockCanvas();
if(frameBuffer != null) { // Fix for mysterious bug ( FATAL EXCEPTION: Thread)
// The viewing area of our virtual screen on our real screen
// Composition
// First layer (bottom)
frameBuffer.drawBitmap(this.gameScreen, null, game.getWSScreen().getGameScreendst(), null);
// Second layer (top)
frameBuffer.drawBitmap(this.gameScreenExtended, null, game.getWSScreen().getGameScreenextendeddst(), null);
holder.unlockCanvasAndPost(frameBuffer);
}
else {
gameEngineLog.e(classTAG, "Surface has not been created or otherwise cannot be edited");
}
}
public void resume() {
this.running = true;
gameloop = new Thread(this);
gameloop.start();
}
public void pause() {
this.running = false;
running = false;
while(true) {
try {
gameloop.join();
break;
} catch (InterruptedException e) {
// retry
}
}
}
}
public void onDraw() {
}