2013-08-28 21 views
1

我已经尝试过一些方法来做到这一点,并没有停止。 我有启动3线程的MainActivity。我想在用户按下“返回”底部时或由于某种原因应用程序停止(例如电话呼叫)时停止线程。 并且在活动再次出现后(当用户回到应用程序时),线程将从他们停止的地方继续。 MainActivity中定义的所有线程以及它们在那里启动。 谢谢!如何使用线程暂停活动并在之后恢复 - android

public class MainActivity extends Activity 
{ 

    //threads 
    private PingPongGame gameThread; 
    private PaddleMover paddleMoverThread; 
    private PresentThread giftThread; 


    public GameSounds gameSounds; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     super.onCreate(savedInstanceState); 


     gameLevel = new GameLevel0(screenWidth , screenHeight, this.giftArr); 

     gameLevelView = new GameLevelView(this,gameLevel); 

     // Creating the game view 
     this.gameView = new PingPongView(this); 


     // Setting the gameView as the main view for the PingPong activity. 
     setContentView(gameView); 


if(gameThread == null){ 
     //create the main thread 
     gameThread = new PingPongGame(gamePaddle, gameView, gameLevel , message , ballArr , gameSounds); 

     //create the thread responsible for moving the paddle 
     paddleMoverThread = new PaddleMover(gamePaddle, gameView); 

     //create the thread responsible for present 
     giftThread = new PresentThread(gamePaddle , gameView , gameLevel, message , giftArr , ballArr,gameSounds); 

     gameThread.start(); 
     paddleMoverThread.start(); 
     giftThread.start(); 

} 
    } 

    //This method is automatically called when the user touches the screen 
    @Override 
    public boolean onTouchEvent(MotionEvent event) 
    { 
     float destination; 
    // Toast.makeText(this, "try!", Toast.LENGTH_SHORT).show(); 
     //get the x coordinate of users' press 
     destination = event.getX(); 

     //notify the paddle mover thread regarding the new destination 
     gamePaddle.setPaddleDestination(destination); 

     return true; 
    } 
} 

我一个线程的实例:

public class PaddleMover extends Thread 
{ 
    private Tray gamePaddle; //holds a reference to the paddle 
    private PingPongView gameView; //holds a reference to the main view 

    //for stop 
    private Object mPauseLock; 
    private boolean mPaused; 


    //initialize class variables 
    public PaddleMover(Tray thePaddle, PingPongView mainView) 
    { 
     gamePaddle = thePaddle; 
     gameView = mainView; 

     //for stop and resume threads 
     mPauseLock = new Object(); 
     mPaused = false; 
    } 

    //main method of the current thread 
    @Override 
    public void run() 
    { 
     //infinitely loop, and move the paddle if necessary 
     while ((Const.isLose == false) && (Const.isCompleteThisLevel==false) && (Const.isDestroy == false)) 
     { 
      //check whether the paddle should be moved 
      if (gamePaddle.getMiddle() != gamePaddle.getPaddleDestination()) 
      { 
       //move the paddle 
       gamePaddle.move(); 

       //send a request to refresh the display 
       gameView.postInvalidate(); 
      } 
      try 
      { 
       PaddleMover.sleep(3); 
      } 
      catch (InterruptedException e) 
      { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

      //for stop and resume 
      synchronized (mPauseLock) { 
       while (mPaused) { 
        try { 
         mPauseLock.wait(); 
        } catch (InterruptedException e) { 
        } 
       } 
      } 

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

    /** 
    * Call this on resume. 
    */ 
    public void onResume() { 
     synchronized (mPauseLock) { 
      mPaused = false; 
      mPauseLock.notifyAll(); 
     } 
    } 
} 
+0

你有没有检查过? http://stackoverflow.com/questions/6776327/how-to-pause-resume-thread-in-android – Rahul

+0

是的。也许我在onCreate中做错了什么?我将用代码编辑我的问题。 – user1932595

+0

当您的活动暂停时,您是否在所有线程上调用了'onResume'方法?在发布的代码中没有看到该实现。如果您的支持Back按钮(从栈中弹出活动)请记住您的活动已被破坏,因此您必须将线程的状态保存在数据库或其他地方,以便稍后可以恢复它们。 –

回答

0

可以实现与使用Runnable对象的线程有很多更好的控制。代替使用run()方法内的循环确定的逻辑,执行以下操作:

  1. 定义您逐帧逻辑Runnable对象内的每个线程。覆盖run()方法。不要在Runnable中使用while循环。

  2. 创建一个跟踪您的游戏是否暂停的变量。使用此变量在主线程中创建一个while()循环。

  3. 定义一个Thread类并获取它的Handler。你可以这样做,像这样:

    class WorkerThread extends Thread 
    { 
        private volatile Handler mHandler; 
        //volatile so you can try to acquire it until it is instantiated 
    
        @Override 
        public void run() 
        { 
         //This is pretty much boilerplate for worker thread implementations 
         Looper.prepare(); 
         //Handlers must be instantiated by their respective threads 
         mHandler = new Handler(); 
         Looper.loop(); 
        } 
    
        @Override 
        public Handler getHandler() 
        { 
         return mHandler; 
        } 
    } 
    
  4. 实例化多个WorkerThreads,并获得他们的处理程序对象的引用。

  5. 在每个框架中,使用postRunnable()方法将Runnable()传递给Handler,该Runnable()定义要执行Thread的逻辑。
  6. 使用ConditionVariable对象确保您在WorkerThread仍在执行时不调用postRunnable()方法。

    Runnable thread1runnable = new Runnable() 
    { 
        @Override 
        public void run() 
        { 
         //Do your logic here 
         ... 
         thread1finished.open(); //This lets the block() function return 
        } 
    } 
    
    ConditionVariable thread1finished = new ConditionVariable(); 
    
    thread1finished.open(); //Make sure the loop doesn't block the first time through 
    
    Thread thread1 = new WorkerThread(); 
    //Start the thread to acquire the handler and prepare it for looping 
    thread1.start(); 
    //Call stop() when shutting down your game, not pausing 
    
    Handler thread1handler; 
    while (thread1handler != null) 
        thread1handler = thread1.getHandler(); 
    //A crude way of making sure you acquire the instantiated handler, you can top this 
    
    while (gameRunning) 
    { 
        if (!isPaused) //Stops work when your isPaused variable is set 
        { 
         thread1finished.block(); //Wait for the last runnable to finish 
         //Lock the ConditionVariable so the loop will block 
         thread1finished.close(); 
         //Signal the worker thread to start crunching 
         thread1handler.postRunnable(thread1runnable); 
        } 
    } 
    
  7. 在你的onPause()重写,设置从张贴Runnable对象到您的WorkerThreads停止你的while()循环变量。享受自动启动和停止!

可能会出现问题,将此方法适用于您不希望同步帧每帧的三个不同线程。让我知道事情的后续。