## Android 關(guān)于系統(tǒng)回收的知識(shí)整理
---
#### 問題背景
```
//在Activity中啟動(dòng)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中啟動(dòng)Thread
public class Application {
public void onCreate() {
...
new MyThread().start();
}
}
現(xiàn)象: 當(dāng)系統(tǒng)回收或者異常崩潰時(shí),在Application中啟動(dòng)的thread仍然在運(yùn)//行,而在Activity中啟動(dòng)的thread則會(huì)停
```
因此岸浑,有以下四個(gè)問題:
1. 為什么會(huì)發(fā)生這個(gè)現(xiàn)象州泊?
**原因其實(shí)很簡(jiǎn)單旁蔼,自己犯錯(cuò)了脱惰,由于系統(tǒng)回收后或者系統(tǒng)異常崩潰后双絮,都會(huì)調(diào)用Application.onCreate()之剧。其實(shí)是崩潰或者回收后調(diào)用onCreate()重新啟動(dòng)了一個(gè)Thread**
2. 系統(tǒng)回收時(shí),是以哪個(gè)維度(組件战授,進(jìn)程還是線程)页藻?
Android是一個(gè)Linux系統(tǒng),為了方便管理應(yīng)用間的私有數(shù)據(jù)植兰,Android應(yīng)用程序在系統(tǒng)中對(duì)應(yīng)一個(gè)userid份帐,而用用相同userid的應(yīng)用程序?qū)⑦\(yùn)行在同一個(gè)**進(jìn)程**中,共享同一個(gè)Dalvik虛擬機(jī)楣导。所以废境,基于操作系統(tǒng)上進(jìn)程與線程的關(guān)系,可以得出結(jié)論,**一個(gè)應(yīng)用程序至少對(duì)應(yīng)一個(gè)進(jìn)程噩凹,進(jìn)程中至少有一個(gè)主線程巴元,即UI線程**
3. 為什么系統(tǒng)回收后,或者系統(tǒng)異常崩潰后驮宴,會(huì)調(diào)用Application.onCreate()?
**目前還沒查到資料**
4. 如何中止一個(gè)thread?
方案一逮刨,使用標(biāo)識(shí)變量
```
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
}
}
}
```
這種方案的問題在于,當(dāng)thread正在休眠時(shí)調(diào)用了stopMe()堵泽,進(jìn)程不能立即停止修己。因此就有了使用中斷機(jī)制的方案二。
```
public MyThread extends Thread {
public void stopMe() {
interrupt();
}
public void run() {
super.run();
while (!isInterrupted()) {
try {
Thread.sleep(...);
// do something
} catch (InterruptException e) {
break;
}
}
}
}
```
兩點(diǎn)需要說明:
1. 當(dāng)thread在阻塞狀態(tài)迎罗,即執(zhí)行了Thread.sleep()時(shí)睬愤,如果發(fā)起中斷,則會(huì)拋出中斷異常被捕捉佳谦,直接用break跳出循環(huán)
2. 當(dāng)thread不在阻塞狀態(tài)戴涝,如果發(fā)起中斷滋戳,則isInterrupted()會(huì)發(fā)揮true钻蔑,直接跳出循環(huán)