How to pause/resume thread in Android?
Asked Answered
M

2

35

I have a thread that running into an activity. I don't want that the thread continuos running when the user click the home button or, for example, the user receive a call phone. So I want pause the thread and resume it when the user re-opens the application. I've tried with this:

protected void onPause() {
  synchronized (thread) {
    try {
      thread.wait();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
  super.onPause();
}
protected void onResume() {
  thread.notify();
  super.onResume();
}

It stops the thread but don't resume it, the thread seems freezed.

I've also tried with the deprecated method Thread.suspend() and Thread.resume(), but in this case into Activity.onPause() the thread doesn't stop.

Anyone know the solution?

Mollymollycoddle answered 21/7, 2011 at 12:52 Comment(0)
S
69

Use wait() and notifyAll() properly using a lock.

Sample code:

class YourRunnable implements Runnable {
    private Object mPauseLock;
    private boolean mPaused;
    private boolean mFinished;

    public YourRunnable() {
        mPauseLock = new Object();
        mPaused = false;
        mFinished = false;
    }

    public void run() {
        while (!mFinished) {
            // Do stuff.

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

}
Serajevo answered 21/7, 2011 at 13:2 Comment(7)
It runs, thanks! But why I must call the wait and notifyAll methods on an Object into the thread and not directly on the thread-object?Mollymollycoddle
Try reading this -> java.sun.com/docs/books/jls/second_edition/html/memory.doc.htmlSerajevo
(1) Is it possible to use the above code within IntentService instead of Runnable? (2) why is it not mPauseLock.notify() instead of notifyAll()?Lessen
Thanks for this, however whenever I run this for my app it exits with FATAL EXCEPTION: THREAD-10 and a null pointer exception.Eburnation
Where do I set the delay... how fast the runnable will 'run' per turn?Embrace
I had studied this a time long ago on Vijay Garg's book "Concurrent and Distributed Computing in Java", but somehow I had forgotten what I had to do to pause a looping thread, but had somehow forgotten the technique. Your code is a textbook example of how it should be done, and properly!Kiangsu
what if // Do Stuff consist of running a while loop for a limited seconds, like int i=100; , while (i>0){Thread.sleep(500); i--;} . how will the pause mechanism work then?Staley
K
4

Try the below code it will work

Thread thread=null;

OnResume()

  public void onResume(){
  super.onResume();
  if(thread == null){
  thread = new Thread()
  {
      @Override
      public void run() {
          try {

              }
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }
  };

  thread.start();
      }
  }

onPause()

@Override
 public void onPause(){
super.onPause();
if(thread != null){
Thread moribund = thread;
thread = null;
moribund.interrupt();
}
}
Kicker answered 21/7, 2011 at 13:27 Comment(2)
This looks simple.. are there problems that could arise from this? Why not just thread.interrupt? Is it nullified first to kill other references to it or something?Seawright
well, it is not pausing/resuming. It is destroying/recreating. Can be performance killer on android, which has Auto Screen Rotation turned on, and user will be continuously shaking the device causing screen to autorotate.Weakwilled

© 2022 - 2024 — McMap. All rights reserved.