正常情况下,当线程中的run方法执行完毕后,线程是会自动关闭,不需要我们手动去关闭的。
如:
new Thread(new Runnable() {
@Override
public void run() {
//执行操作
}
}).start();
该线程在run方法中的操作执行完毕后,线程会自动关闭。
而当run方法中的操作会不断循环执行时如:
new Thread(new Runnable() {
@Override
public void run() {
while (true){
//执行操作
}
}
}).start();
这个线程中run方法会循环执行,并不会中断,所以线程一会一直执行,Android中如果不做终止,即使退出activity也会一直执行,所以我们需要手动终止线程,终止线程的方法:
1.Thread.stop(),该方法是暴力停止线程不推荐使用,已经废弃。
2.使用标记位来停止,如下面例子,如果我们要在activity 销毁时退出线程:
private void stopThread(){
mThread = new Thread(new Runnable() {
@Override
public void run() {
while (true){
//执行操作
if (isStopThread){
break;
}
}
}
});
mThread.start();
}
@Override
protected void onDestroy() {
super.onDestroy();
isStopThread = true;
}
isStopThread变量来判断是否退出线程,如需要退出就直接退出循环,线程终止。
3.使用interrupt方法来停止线程:
private void stopThread(){
mThread = new Thread(new Runnable() {
@Override
public void run() {
while (true){
//执行操作
if (mThread.isInterrupted()){
break;
}
}
}
});
mThread.start();
}
@Override
protected void onDestroy() {
super.onDestroy();
mThread.interrupt();
}
我们使用mThread.interrupt来中断线程,在run方法中使用mThread.isInterrupted()来判断线程是否中断,如果中断责跳出循环,这个标识位的原理其实是一样的。mThread.interrupt并不是强行中断线程,只是给线程设置一个标志,告诉线程我需要中断。
接下来我们看下线程阻塞的情况下:
private void stopThread(){
mThread = new Thread(new Runnable() {
@Override
public void run() {
while (true){
//执行操作
Log.e(TAG,"线程执行中..is interrupted = " + mThread.isInterrupted());
if (mThread.isInterrupted()){
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
Log.e(TAG,"出现异常");
}
}
}
});
mThread.start();
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e(TAG,"退出activity");
mThread.interrupt();
}
我们看下log:
从log中我们看到退出activity时,线程阻塞抛出了异常,而mThread.isInterrupted()仍然为false,所以线程并没有被中断,这是因为现在进入阻塞时调用mThread.interrupt()方法,会抛出异常同时还会调用interrupted()方法,把isInterrupted恢复称false,所以线程不会被终止,
解决方法很简单我们只要在出现异常中退出循环就可以了:
while (true){
//执行操作
Log.e(TAG,"线程执行中..is interrupted = " + mThread.isInterrupted());
if (mThread.isInterrupted()){
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
Log.e(TAG,"出现异常");
break;
}
}