使用thread.join从surfaceview结束android活动

时间:2013-08-24 23:24:22

标签: java android multithreading android-activity surfaceview

我正在开发我的第一个Android应用程序 - 蛇。现在我正试图为该应用程序实现“游戏结束”。所以基本上当蛇撞到墙上时,app应该问你的名字并把它作为你在HiScore上的分数。好吧,我正在敲打墙片。我正在尝试线程,到目前为止,我发现没有办法阻止它而不会出错。

我google了很多,每个人都说那个thread.join();正在等待线程结束,那么结束每半秒绘制一次简单方块的线程需要多长时间?当我在播放时按下手机上的后退按钮时,暂停();功能完美。日志“游戏已结束”出现在LogCat上。

所以问题是,当蛇撞到墙壁时,我无法停止此活动,日志“游戏已结束”永远不会发生。那是为什么?

我的代码:

public class SnakeCage extends SurfaceView implements Runnable{

    // blah blah .. functions that draw and stuff ..


    public void pause() {
        isRunning = false;
        while(true){
            try {
                aThread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            break;
        }
        aThread = null;
    Log.d("pause()","game has ended"); // <<<<<<<<<THIS ONE>>>>>>>>>
    }

    public void resume() {
        isRunning = true;       
        aThread = new Thread(this);
        aThread.start();
    }

    public void init(){
        // blah blah...
    }


    private void gameOver() {
    int pHeadX = snakeHead.posX;
    int pHeadY = snakeHead.posY;

        Log.d("gameOver()", "checking");

        if(pHeadY<0 || pHeadX<0 || pHeadX>23 || pHeadY>19){

            Log.d("gameOver()", "game now will end");
            gameOver = true;
        }
    }

    public void run() {

        while (isRunning){
            if(!aHolder.getSurface().isValid())
                continue;

            canvas = aHolder.lockCanvas();

            // drawing

            gameOver();
            if(gameOver) break;

            // more drawing 


            aHolder.unlockCanvasAndPost(canvas);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        if(gameOver){
                 pause();
        }
    }

和活动类:

public class PlayingActivity extends Activity implements OnClickListener{

    SnakeCage v;
    Button snakeGoUp;
    Button snakeGoDown;
    Button snakeGoLeft;
    Button snakeGoRight;

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

        setContentView(R.layout.frame_layout);
        v = (SnakeCage)findViewById(R.id.sView);

        // listeners and stuff

    }


    @Override
    protected void onPause() {
        super.onPause();
        v.pause();
    }


    @Override
    protected void onResume() {
        super.onResume();
        v.resume();
    }


    @Override
    public void onClick(View view) {
        switch(view.getId()){

        case R.id.snakeUp:
            v.move(1);
            break;

        case R.id.snakeDown:
            v.move(2);
            break;

        case R.id.snakeLeft:
            v.move(3);
            break;

        case R.id.snakeRight:
            v.move(4);
            break;
        }

    }
}

2 个答案:

答案 0 :(得分:2)

我刚刚做了:

Context context = getContext();
((PlayingActivity)context).finish();

从:

How can I end an activity from inside a SurfaceView class or nested thread

虽然它不能让我满意......现在已足够了

答案 1 :(得分:1)

我建议使用LocalBroadcastManager向Activity发送消息,通知它自杀。你可以在Activity中拥有一个内部类来接收广播,并在Activity中调用一个私有方法来结束它。

public class MyActivity extends Activity {

    public void onCreate(Bundle state) {
        LocalBroadcastManager.getInstance(this).registerReceiver(new MessageHandler(),
                                                             new IntentFilter("kill"));
    }

    private void killActivity() {
        finish();
    }

    public class MessageHandler extends BroadcastReceiver {
        onReceive(Context context, Intent intent) {
            killActivity();
        }

}

然后在您的SurfaceView中,您需要做的就是:

Intent intent = new Intent("kill");
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);

它的代码多一点,但恕我直言的更清晰。