如何暂停活动与线程和事后恢复 - android

时间:2013-08-28 18:20:52

标签: android multithreading

我已经尝试了一些方法来做到这一点,并没有做到。 我有MainActivity,它启动3个线程。当用户按下“返回”底部或者由于某种原因应用程序停止(例如电话)时,我想停止线程。 并且在再次看到活动之后(当用户回到应用程序时),线程将从他们停止的地方继续。 MainActivity中定义的所有线程都在那里开始。 谢谢!

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();
        }
    }
}

1 个答案:

答案 0 :(得分: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并获取对其Handler对象的引用。

  5. 在每个框架中,使用postRunnable()方法传递Runnable(),该Runnable()将您希望Thread执行的逻辑传递给Handler。
  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()重写中,设置停止while()循环的变量,将Runnable对象发布到WorkerThreads。享受自动启动和停止!

  8. 将此方法适用于三个不同的线程可能会出现问题,您不希望同步每帧帧数。让我知道它是怎么回事。