如何从渲染线程中显示对话框?

时间:2011-03-15 01:42:26

标签: java android

我的游戏问题在这里。我有点不明白Android如何处理对话框。当我从一个活动中调用对话框时,它会起作用:

public class RocketActivity extends GameActivity implements onGameFinishedListener {

private final int MENU = 0;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //some codes here
    setContentView(layout);
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    switch (keyCode) {
    //case KeyEvent.KEYCODE_BACK:
        //return true;
    case KeyEvent.KEYCODE_MENU:
        showDialog(MENU);
        break;
    default:
        break;
    }
    return super.onKeyDown(keyCode, event);    
}

@Override
protected Dialog onCreateDialog(int id) {

    return new AlertDialog.Builder(RocketActivity.this)
        .setIcon(android.R.drawable.ic_dialog_alert)
        .setTitle(com.fugo.Rocket.R.string.dialog_pause_title)
        .setPositiveButton(string.dialog_button_reset, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                RocketActivity.this.rocketView.init();
            }
        })
        .setNegativeButton(string.dialog_button_cancel, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        }).create();
    }
}

在那里,代码完美运行,对话框显示在前面。但后来我尝试从绘图线程中显示对话框(我打算在某些条件后调用gameFinished())对话框没有显示。

GameThread.java

package com.fugo.Rocket.Engine;

import android.graphics.Canvas;
import android.util.Log;
import android.view.SurfaceHolder;

public class GameThread extends Thread {


    private SurfaceHolder surfaceHolder;
    private GameView gameView;
    private boolean run;

    public GameThread(SurfaceHolder surfaceHolder, GameView gameView) {
        this.surfaceHolder = surfaceHolder;
        this.gameView = gameView;
    }

    public SurfaceHolder getSurfaceHolder() {
        return surfaceHolder;
    }

    public GameView getGameView() {
        return gameView;
    }
    public void setRunning(boolean run) {
        this.run = run;
    }

    @Override
    public void run() {

        Canvas c;
        Log.d(TAG, "starting game loop");
        while(run) {
            c = null;
            try {
                c = this.surfaceHolder.lockCanvas(null);
                synchronized(surfaceHolder) {

                    this.gameView.Update(FRAME_PERIOD);
                    //render state to the screen
                    //draws the canvas on the panel
                    this.gameView.onDraw(c);
                }
            }
            catch (Exception e) {
            }
            finally {
                //in case on an exception the surface is not left in
                //an inconsistent state
                if(c != null) {
                    surfaceHolder.unlockCanvasAndPost(c);
                }
            }
        }
    }
}

GameView.java

package com.fugo.Rocket.Engine;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.fugo.Rocket.Engine.EventListener.onGameFinishedListener;

public abstract class GameView extends SurfaceView implements SurfaceHolder.Callback{

    List<onGameFinishedListener> listeners;
    public GameThread gameThread;
    protected int width;
    protected int height;
    public GameView(Context context) {
        super(context);
        width = 320;
        height = 480;
        listeners = new ArrayList<onGameFinishedListener>();
    }

    public abstract void init();
    public void registerGameFinishedListener(onGameFinishedListener listener) {
        listeners.add(listener);
    }
    protected void GameFinished(GameView gameView) {
        for (onGameFinishedListener listener : listeners) {
            synchronized(gameThread.getSurfaceHolder()) {
                listener.onGameFinished(gameView);
            }
        }
    }

    public void Update(float gameTime) {
        if(finished)
        {
            GameFinished(this);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        this.width = w;
        this.height = h;
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        startThread();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        stopThread();
    }

    public void startThread() {
        gameThread.setRunning(true);
        gameThread.start();

    }
    public void stopThread() {
        boolean retry = true;
        gameThread.setRunning(false);
        while(retry) {
            try {
                gameThread.join();
                retry = false;
            }
            catch(InterruptedException e) {

            }
        }
    }
}

我有一个onGameFinishedListener界面,如上所示,由活动实现。

package com.fugo.Rocket.Engine.EventListener;

import com.fugo.Rocket.Engine.GameView;

public interface onGameFinishedListener {

    public void onGameFinished(GameView gameView);

}

package com.fugo.Rocket.Activities;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.RelativeLayout;

import com.fugo.Rocket.RocketView;
import com.fugo.Rocket.Engine.GameActivity;
import com.fugo.Rocket.Engine.GameView;
import com.fugo.Rocket.Engine.EventListener.onGameFinishedListener;
import com.fugo.Rocket.R.string;

public class RocketActivity extends GameActivity implements onGameFinishedListener {

    @Override
    public void onGameFinished(GameView gameView) {
        showDialog(END);
        //startActivity(new Intent(this, StartMenuActivity.class));
    }

}

那么当游戏结束时,它应该显示对话框。但最终它不会出现。我试图分析这个问题,我认为问题是通过gameThread调用对话框。

GameThread&gt;更新&gt; gameFinish&gt;显示对话框

任何人都有解决方案或更好的方式来实施此游戏结束活动?

1 个答案:

答案 0 :(得分:2)

所有UI工作必须从UI线程完成。您无法从非UI线程显示对话框。您可以使用runOnUiThread使该部分在正确的线程上运行。