Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 多次更新SurfaceView的更好方法?_Android_Performance - Fatal编程技术网

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() {

}