## Android 关于系统回收的知识整理
---
#### 问题背景
```
//在Activity中启动Thread
public class MyActivity extends Activity {
public void onCreate() {
...
new MyThread().start();
}
class MyThread extends Thread {
public void run() {
super.run();
while(true) {
Thread.sleep(10 * 1000);
}
}
}
}
//在Application中启动Thread
public class Application {
public void onCreate() {
...
new MyThread().start();
}
}
现象: 当系统回收或者异常崩溃时,在Application中启动的thread仍然在运//行,而在Activity中启动的thread则会停
```
因此,有以下四个问题:
1. 为什么会发生这个现象?
**原因其实很简单,自己犯错了,由于系统回收后或者系统异常崩溃后,都会调用Application.onCreate()。其实是崩溃或者回收后调用onCreate()重新启动了一个Thread**
2. 系统回收时,是以哪个维度(组件,进程还是线程)?
Android是一个Linux系统,为了方便管理应用间的私有数据,Android应用程序在系统中对应一个userid,而用用相同userid的应用程序将运行在同一个**进程**中,共享同一个Dalvik虚拟机。所以,基于操作系统上进程与线程的关系,可以得出结论,**一个应用程序至少对应一个进程,进程中至少有一个主线程,即UI线程**
3. 为什么系统回收后,或者系统异常崩溃后,会调用Application.onCreate()?
**目前还没查到资料**
4. 如何中止一个thread?
方案一,使用标识变量
```
public MyThread extends Thread {
private violate boolean mFlag = false;
public void stopMe() {
this.mFlag = true;
}
public void run() {
super.run();
while (!mFlag) {
Thread.sleep(..);
// do something
}
}
}
```
这种方案的问题在于,当thread正在休眠时调用了stopMe(),进程不能立即停止。因此就有了使用中断机制的方案二。
```
public MyThread extends Thread {
public void stopMe() {
interrupt();
}
public void run() {
super.run();
while (!isInterrupted()) {
try {
Thread.sleep(...);
// do something
} catch (InterruptException e) {
break;
}
}
}
}
```
两点需要说明:
1. 当thread在阻塞状态,即执行了Thread.sleep()时,如果发起中断,则会抛出中断异常被捕捉,直接用break跳出循环
2. 当thread不在阻塞状态,如果发起中断,则isInterrupted()会发挥true,直接跳出循环