2012-10-29 25 views
0

我正在使用SurfaceView工作在Android游戏上,游戏工作正常,所以我想在用户点击HOME键时暂停它,但是当返回SurfaceView消失时(黑色背景编辑:有时候绘图出现)和按钮在这两种情况下都是不活动的,然后我得到ANR。Surfaceview ANR onResume

public class MainActivity extends Activity { 
    private Game game; 
    MainPanel mp; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     game = new Game(); 
     LoadLevel(); 
     Init(); 
     setContentView(R.layout.main);//contains surfaceview and buttons 
     mp = (MainPanel) findViewById(R.id.SurfaceView01); 
     mp.Init(game,this); 
     Button btnTop = (Button) findViewById(R.id.buttonTop); 
     Button btnBottom = (Button) findViewById(R.id.buttonBottom); 
     Button btnLeft = (Button) findViewById(R.id.buttonLeft); 
     Button btnRight = (Button) findViewById(R.id.buttonRight); 
     btnTop.setOnClickListener... 
    } 

    private void Init() { 
     ... 
    } 

    public void LoadLevel() { 
     ... 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     Log.d("Tag","Resume"); 
    } 

    @Override 
    protected void onPause() { 
      super.onPause(); 
     Log.d("Tag","Pause"); 
    } 
} 

public class MainPanel extends SurfaceView implements SurfaceHolder.Callback { 

    private MainThread thread; 
    private Game game; 
    private MainActivity act; 

    public MainPanel(Context context, AttributeSet attrs) { 
     super(context,attrs); 
     getHolder().addCallback(this); 
    } 

    public MainThread getThread() { 
     return thread; 
    } 

    public void Init(Game game, MainActivity act){ 
     this.game = game; 
     this.act = act; 
    } 

    public void Move(int dir) { 
     ... 
    } 

    public void update() { 
     ... 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {} 
    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     if (thread == null) { 
      thread = new MainThread(getHolder(), this); 
      thread.Start(); 
      thread.start(); 
     } 
    } 
    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     thread.Stop(); 
     boolean retry = true; 
     while (retry) { 
      try { 
       thread.join(); 
       retry = false; 
      } catch (InterruptedException e) {} 
     } 
     thread = null; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     canvas.drawColor(Color.BLACK); 
     //drawing... 
    } 
} 

public class MainThread extends Thread { 
    private final static int MAX_FPS = 30; 
    private final static int MAX_FRAME_SKIPS = 3; 
    private final static int FRAME_PERIOD = 1000/MAX_FPS; 

    private SurfaceHolder surfaceHolder; 
    private MainPanel gamePanel; 
    private boolean run = false; 
    private boolean start = false; 

    public MainThread(SurfaceHolder surfaceHolder, MainPanel gamePanel) { 
     super(); 
     this.surfaceHolder = surfaceHolder; 
     this.gamePanel = gamePanel; 
    } 

    public void Start() { 
     this.run = true; 
     this.start = true; 
    } 

    public void Pause() { 
     this.start = false; 
    } 

    public void Resume() { 
     this.start = true; 
    } 
    public void Stop() { 
     this.run = false; 
    } 

    @Override 
    public void run() { 
     Canvas c = null; 
     long beginTime;  // the time when the cycle begun 
     long timeDiff;  // the time it took for the cycle to execute 
     int sleepTime;  // ms to sleep (<0 if we're behind) 
     int framesSkipped; // number of frames being skipped 

     while(run) { 
      while(start) { 
       try { 
        c = surfaceHolder.lockCanvas(null); 
        synchronized (surfaceHolder) { 
         beginTime = System.currentTimeMillis(); 
         framesSkipped = 0; // resetting the frames skipped 
         // update game state 
         gamePanel.update(); 
         // render state to the screen draws the canvas on the panel 
         if(c!=null) gamePanel.onDraw(c); 
         // calculate how long did the cycle take 
         timeDiff = System.currentTimeMillis() - beginTime; 
         // calculate sleep time 
         sleepTime = (int)(FRAME_PERIOD - timeDiff); 

         if (sleepTime > 0) { 
          // if sleepTime > 0 we're OK 
          try { 
           // send the thread to sleep for a short period very useful for battery saving 
           Thread.sleep(sleepTime); 
          } catch (InterruptedException e) {} 
         } 

         while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) { 
          // we need to catch up update without rendering 
          gamePanel.update(); 
          // add frame period to check if in next frame 
          sleepTime += FRAME_PERIOD; 
          framesSkipped++; 
         } 
        } 
       } finally { 
        if (c != null) surfaceHolder.unlockCanvasAndPost(c); 
       } 
      } 
     } 
    } 
} 
+1

你对''onPause''方法的重写似乎缺少''super.onPause()''调用。 – harism

+0

我只是在复制时忘记了它 –

回答

0

THX这一职务why is my runnable giving ANR?我可以解决这个问题,我从孤立的UI线程MainThread进一步的细节检查的最佳答案。