My service spawns a new thread, and stops it according to the typically recommended java method of interrupt()'ing. When I stop the service, I stop the thread in onDestroy(). The service is stopped, and the interrupt code is reached. However, soon enough the thread restarts from the beginning of the Runnable.
public class DoScan extends Service {
public volatile Thread runner;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
startThread();
}
@Override
public void onDestroy() {
super.onDestroy();
android.util.Log.v("@@@@@@@@@@@@@@@@@@@@", "DoScan.onDestroy");
stopThread();
}
public synchronized void startThread(){
if(runner == null){
android.util.Log.v("@@@@@@@@@@@@@@@@@@@@", "DoScan.startthread");
runner = new Thread(new ScanningThread());
runner.start();
}
}
/* use a handler in a loop cycling through most of oncreate.
* the scanningthread does the work, then notifies the svc's uithread
*/
public synchronized void stopThread(){
if(runner != null){
android.util.Log.v("@@@@@@@@@@@@@@@@@@@@", "DoScan.stopthread");
Thread moribund = runner;
runner = null;
moribund.interrupt();
android.util.Log.v("@@@@@@@@@@@@@@@@@@@@", "interrupted?" + moribund.isInterrupted());
}
}
}
I think the safest way is to have a flag so the thread checks for it inside its main loop.
class ScanningThread extends Thread {
// Must be volatile:
private volatile boolean stop = false;
public void run() {
while (!stop) {
System.out.println("alive");
}
if (stop)
System.out.println("Detected stop");
}
public synchronized void requestStop() {
stop = true;
}
}
public synchronized void startThread(){
if(runner == null){
android.util.Log.v("@@@@@@@@@@@@@@@@@@@@", "DoScan.startthread");
runner = new ScanningThread();
runner.start();
}
}
public synchronized void stopThread(){
if(runner != null){
android.util.Log.v("@@@@@@@@@@@@@@@@@@@@", "DoScan.stopthread");
runner.requestStop();
runner = null;
}
}
The problem is that your thread needs to cooperate by periodically checking for interruption and exiting if the thread has been interrupted. Unless you place something along the lines of the following in your thread...
// Processing... if ( Thread.interrupted() ){ return; } // More processing... try{ Thread.sleep(sleeptime); }catch(InterruptedException interrupt){ return; } // Rinse and repeat...
...your thread will just ignore the fact that it has been interrupted. The method proposed by Lucas S. is essentially identical, except that using interruption will generate an exception if the thread is blocked, whereas under Lucas S.'s method, you might have to wait indefinitely for the thread to quit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With