0

)

我有一个如下所示的 onCreate 方法:

  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    boolean isLandscape = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
    int frameBufferWidth = isLandscape ? 480 : 320;
    int frameBufferHeight = isLandscape ? 320 : 480;
    Bitmap frameBuffer = Bitmap.createBitmap(frameBufferWidth,
            frameBufferHeight, Config.RGB_565);

    float scaleX = (float) frameBufferWidth
            / getWindowManager().getDefaultDisplay().getWidth();
    float scaleY = (float) frameBufferHeight
            / getWindowManager().getDefaultDisplay().getHeight();

    renderView = new AndroidFastRenderView(this, frameBuffer);
    graphics = new AndroidGraphics(getAssets(), frameBuffer);
    fileIO = new AndroidFileIO(this);
    audio = new AndroidAudio(this);
    input = new AndroidInput(this, renderView, scaleX, scaleY);
    screen = getStartScreen();
    setContentView(renderView);

    PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "GLGame");
}

有趣的是:

renderView = new AndroidFastRenderView(this, frameBuffer);

AndroidFastRenderView(this, frameBuffer) 类的代码:

public class AndroidFastRenderView extends SurfaceView implements Runnable {
    AndroidGame game;
    Bitmap framebuffer;
    Thread renderThread = null;
    SurfaceHolder holder;
    volatile boolean running = false;

    public AndroidFastRenderView(AndroidGame game, Bitmap framebuffer) {
        super(game);
        this.game = game;
        this.framebuffer = framebuffer;
        this.holder = getHolder();
    }

    public void resume() { 
        running = true;
        renderThread = new Thread(this);
        renderThread.start();         
    }      

    public void run() {
        Rect dstRect = new Rect();
        long startTime = System.nanoTime();
        while(running) {  
            if(!holder.getSurface().isValid())
                continue;           

            float deltaTime = (System.nanoTime()-startTime) / 1000000000.0f;
            startTime = System.nanoTime();

            game.getCurrentScreen().update(deltaTime);
            game.getCurrentScreen().present(deltaTime);

            Canvas canvas = holder.lockCanvas();
            canvas.getClipBounds(dstRect);
            canvas.drawBitmap(framebuffer, null, dstRect, null);
            holder.unlockCanvasAndPost(canvas);
        }
    }

    public void pause() {                        
        running = false;                        
        while(true) {
            try {
                renderThread.join();
                return;
            } catch (InterruptedException e) {
                // retry
            }
        }
    }        
    }

稍后在我的 Activity 中有一个 onResume 方法,该方法在 onCreate 之后立即执行:

 @Override
        public void onResume() {
            super.onResume();
            wakeLock.acquire();
            screen.resume();
            renderView.resume();
        }

在这里你可以看到 renderView 对象的 resume 方法被执行,它创建了一个新线程(与 AnroidFastRenderView 比较)。

现在我的问题。新线程执行 run 方法包含的代码。这段代码负责在显示器上绘制一些东西。但我不明白在新线程中将执行什么,不执行什么。这是一个可能是屏幕的示例:

public class MainMenuScreen extends Screen {
    public MainMenuScreen(Game game) {
        super(game);               
    }   

    public void update(float deltaTime) {
        Graphics g = game.getGraphics();
        List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
        game.getInput().getKeyEvents();       

        int len = touchEvents.size();
        for(int i = 0; i < len; i++) {
            TouchEvent event = touchEvents.get(i);
            if(event.type == TouchEvent.TOUCH_UP) {
                if(inBounds(event, 0, g.getHeight() - 64, 64, 64)) {
                    Settings.soundEnabled = !Settings.soundEnabled;
                    if(Settings.soundEnabled)
                        Assets.click.play(1);
                }
                if(inBounds(event, 64, 220, 192, 42) ) {
                    game.setScreen(new GameScreen(game));
                    if(Settings.soundEnabled)
                        Assets.click.play(1);
                    return;
                }
                if(inBounds(event, 64, 220 + 42, 192, 42) ) {
                    game.setScreen(new HighscoreScreen(game));
                    if(Settings.soundEnabled)
                        Assets.click.play(1);
                    return;
                }
                if(inBounds(event, 64, 220 + 84, 192, 42) ) {
                    game.setScreen(new HelpScreen(game));
                    if(Settings.soundEnabled)
                        Assets.click.play(1);
                    return;
                }
            }
        }
    }

    private boolean inBounds(TouchEvent event, int x, int y, int width, int height) {
        if(event.x > x && event.x < x + width - 1 && 
           event.y > y && event.y < y + height - 1) 
            return true;
        else
            return false;
    }

    public void present(float deltaTime) {
        Graphics g = game.getGraphics();

        g.drawPixmap(Assets.background, 0, 0);
        g.drawPixmap(Assets.logo, 32, 20);
        g.drawPixmap(Assets.mainMenu, 64, 220);
        if(Settings.soundEnabled)
            g.drawPixmap(Assets.buttons, 0, 416, 0, 0, 64, 64);
        else
            g.drawPixmap(Assets.buttons, 0, 416, 64, 0, 64, 64);
    }

    public void pause() {        
        Settings.save(game.getFileIO());
    }

    public void resume() {

    }

    public void dispose() {

    }
}

在 AnroidFastRenderView 的 run 方法中有两行很重要:

game.getCurrentScreen().update(deltaTime);
game.getCurrentScreen().present(deltaTime);

这两行都执行我的 MainMenuScreen 示例的 update 和 present 方法。在我看来,这仍然会发生在同一个新线程中。所以现在发生的一切都是由新线程完成的。Activity类中的onResume方法之后就没什么可做的了,所以老线程也没什么可做的了。在我看来,没有什么是并行发生的,但这实际上是增加线程的原因。

我哪里错了?

对不起,很长的问题。我希望你能帮助我。

问候彼得

PS:代码来自《Beginning Android Games》一书。

4

0 回答 0