按下主页按钮后重新进入时Android应用程序崩溃。这是代码

时间:2011-12-14 10:52:02

标签: android android-homebutton

我在这个论坛上一遍又一遍地搜索过谷歌关于这个问题,也许它必须与我的线程或游戏如何开始的方式做一些事情。

这是游戏应用程序的骨架,请告诉我我做错了什么。

这就是我在线程中所做的事情;

public class GameThread extends Thread 
{    

static final long FPS = 30;
private GameView view;
private boolean running = false;
private SurfaceHolder surfaceHolder;
public boolean isSurfaceCreated = false;

private Object mPauseLock;
private boolean mPaused;

public GameThread(SurfaceHolder surfaceHolder, Handler handler, GameView view) 
{
    super();
    mPauseLock = new Object();
    mPaused = false;

    this.surfaceHolder = surfaceHolder;
    this.view = view;
}

public void setRunning(boolean run) 
{
      running = run;
}

/**
 * pause thread.
 */
public void onPause() {
    synchronized (mPauseLock) {
        mPaused = true;
    }
}

/**
 * resume thread.
 */
public void onResume() {
    synchronized (mPauseLock) {
        mPaused = false;
        mPauseLock.notifyAll();
    }
}

@Override
public void run() 
{

    // run our thread on high priority to keep from getting slowdown
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);

    // wait for surface to become available @ start
    while (!isSurfaceCreated && running) 
    {
        try {
            sleep(50);
        } catch (InterruptedException e) {}
    }       

    long ticksPS = 1000 / FPS;

    long startTime;

    long sleepTime;

    while (running){

          Canvas c = null;

          startTime = System.currentTimeMillis();

          //long msSinceLastTick = System.currentTimeMillis() - view.lastTickMs;

             try {

                    c = surfaceHolder.lockCanvas(null);

                    synchronized (surfaceHolder) 
                    {

                        /*
                         * stop updating when pause is pressed
                         */
                        if(mPaused == false)
                        {
                            view.update();
                        }

                        view.onDraw(c);

                    }

             } finally {

                    if (c != null) 
                    {

                        surfaceHolder.unlockCanvasAndPost(c);

                    }

             }

             sleepTime = ticksPS - (System.currentTimeMillis() - startTime);

             try {


                    if (sleepTime > 0)

                           sleep(sleepTime);

                    else

                           sleep(10);

             } catch (Exception e) {}

      }

}

这是开始活动代码;

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;

public class test_game extends Activity {
    /** Called when the activity is first created. */

    private GameView Game;

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

        Game = new GameView(this);

    setContentView(Game);

    }

    @Override
    public void onBackPressed() 
    {
        super.onBackPressed();

        //KILL ALL
        finish();
        System.runFinalizersOnExit(true);
        System.exit(0);
    }

 // ===========================================================
 // onPause
 // ===========================================================

 protected void onPause() {
     super.onPause();

 }


 // ===========================================================
 // onStop
 // ===========================================================

 protected void onStop() {
     super.onStop();
 }

 // ===========================================================
 // onDestroy
 // ===========================================================

 @Override
 protected void onDestroy() {
    super.onDestroy();

 }

}

在AndroidManifest.xml中添加了额外的行

      android:launchMode="singleTask" 
      android:alwaysRetainTaskState="true"

GameView看起来像这样;

   public class GameView extends SurfaceView {

   private SurfaceHolder holder;
   private GameThread Thread = null;
   private int testVar = 0;
   private boolean isPaused = false;


   public GameView(Context context) 
   {

         super(context);

     loadGameFiles();

         holder = getHolder();

         Thread = new GameThread(holder, new Handler(), this);

         holder.addCallback(new SurfaceHolder.Callback() 
         {

                @Override
                public void surfaceDestroyed(SurfaceHolder holder) 
                {

                       boolean retry = true;

                       Thread.setRunning(false);

                       while (retry) 
                       {

                              try {

                                    Thread.join();
                                    retry = false;

                              } catch (InterruptedException e) 
                              {

                              }

                       }

                }

                @Override
                public void surfaceCreated(SurfaceHolder holder) 
                {

                    Thread.isSurfaceCreated = true; 

                    if(isPaused == true)
                    {
                        onResume();

                    }

                    Thread.setRunning(true);
                    Thread.start();
                    GameMenu();


                }



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

         });

         setFocusable(true); 

   }



   public boolean isPaused()
   {
       return this.isPaused;
   }

   /**
    * Pauses the physics update & animation.
    */
   public void onPause() {
       synchronized (holder) 
       {
           if(isPaused == false) 
           {   
               isPaused = true;
           Thread.onPause();
           }
       }
   }

   public void onResume()
   {
       synchronized (holder) 
       {
           if(isPaused == true) 
           {   
               isPaused = false;
               Thread.onResume();
           }
       }
   }

   etc..

大家好,感谢您的回复,论坛评论框不允许我发布这个;无论如何,这是:

嗨弗兰肯斯坦,我已经尝试了你在这里提出的建议,但仍然行不通。 GameView中的恢复代码如下所示;

public void onResume(){ synchronized (holder) 
           { if(isPaused == true){   
                   isPaused = false; //resume notification to the gameview
                   Thread.onResume(); //resume the thread
               }
           }
       }

This is on the Activity class;
 @Override
 protected void onPause() {
     super.onPause();
     Game.onPause();
 }
 @Override
 protected void onResume() {
     super.onResume();
     Game.onResume();
 }

我没有使用过logcat,不知道如何使用它,我可以肯定在java的每个步骤中调用它但它在哪里显示错误/日志?先谢谢你们!

当我恢复时,它会在LogCat中显示以下错误;

添加此行以避免上一个问题;

                    Thread.isSurfaceCreated = true; 
                    Thread.setRunning(true);
                    Thread.start();
                    loadGame();

更新 应用程序返回黑屏,但它没有冻结。

Errors (updated) in logcat;
12-14 16:54:52.176: ERROR/MediaPlayerService(3937):  create PVPlayer
12-14 16:55:03.172: ERROR/dalvikvm(4619): Failed to write stack traces to /data/anr/traces.txt (1093 of 3526): Unknown error: 0
12-14 16:55:03.910: ERROR/dalvikvm(25464): Failed to write stack traces to /data/anr/traces.txt (2401 of 3332): Math result not representable
12-14 16:55:03.918: ERROR/dalvikvm(25279): Failed to write stack traces to /data/anr/traces.txt (-1 of 2354): Math result not representable
12-14 16:55:32.394: ERROR/imdg81(19379): IsShutDownStarted()
12-14 16:55:32.590: ERROR/imdg81(19379): IsShutDownStarted()
12-14 16:55:37.902: ERROR/MediaPlayer(19379): error (100, 0)
12-14 16:55:37.930: ERROR/SoundPool(5264): Unable to load sample: (null)
12-14 16:55:39.281: ERROR/SoundBooster(5328): readSBTable: file open error!
12-14 16:55:39.281: ERROR/AcousticEQ(5328): [AEQ] aeqcoe.txt: file open error!
12-14 16:55:39.500: ERROR/AudioService(19379): Media server died.
12-14 16:55:39.500: ERROR/AudioService(19379): Media server started.
12-14 16:55:39.996: ERROR/MediaPlayerService(5328):  create PVPlayer

2 个答案:

答案 0 :(得分:5)

在你的onSurfaceCreated方法中你有这段代码:

  if(isPaused == true){
      onResume();

  }

  Thread.setRunning(true);
  Thread.start();

无论如何调用您对Thread.start()的调用(即使isPaused为真)。由于您的线程已经在这种情况下启动,因此您尝试启动它两次,从而获得非法状态异常。

答案 1 :(得分:2)

谢谢你们!

我已经解决了这个问题,黑屏正在显示,因为线程不是再次创建,而是在我第二次进入屏幕时被操纵。因此,它显示一个空/空线程被操作为黑屏。我已将以下行添加到OnResume()

               if(!Thread.isAlive())
               {
                    Thread = new GameThread(holder, new Handler(), this);
               }

这是我的问题的解决方法,但现在我要实现onSaveInstanceState& onRestoreInstanceState以避免从beginnig重新启动。