以下代码的哪些部分在单独的线程中运行?

时间:2013-08-07 14:35:27

标签: java android multithreading

我有一个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示例的更新和显示方法。在我看来,这仍将发生在同一个新线程中。所以现在发生的一切都是由新线程完成的。在activity类中的onResume方法之后,没有什么可做的,所以旧线程无关。在我看来,没有任何事情发生并行,但这实际上是另一个线程的原因。

我哪里错了?

很抱歉这个问题很长。我希望你能帮助我。

电贺 彼得

P.S。:代码来自“Beginning Android Games”一书。

0 个答案:

没有答案