我的服务生成一个新线程,并根据中断()的typically recommended java方法停止它。当我停止服务时,我在onDestroy()中停止线程。服务停止,并且到达中断代码。但是,很快就会从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());
}
}
}
答案 0 :(得分:12)
我认为最安全的方法是拥有一个标志,以便线程在其主循环中检查它。
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;
}
}
答案 1 :(得分:11)
问题在于,如果线程被中断,您的线程需要通过定期检查中断和退出来进行协作。除非你在线程中放置以下内容......
// Processing... if ( Thread.interrupted() ){ return; } // More processing... try{ Thread.sleep(sleeptime); }catch(InterruptedException interrupt){ return; } // Rinse and repeat...
...你的线程将忽略它已被中断的事实。 Lucas S.提出的方法基本相同,只是如果线程被阻塞,使用中断将生成异常,而在Lucas S.的方法下,您可能必须无限期地等待线程退出。
答案 2 :(得分:0)
中断线程会在线程中抛出异常,但不一定会阻止它。您应该捕获该异常,然后在退出之前进行线程清理(提供,您需要退出!)。