衆所周知,Android主線程需要一直更新UI,否則會造成畫面卡頓,所以API 9以後的版本中是不允許在主線程進行網絡操作的,否則會拋NetworkOnMainThreadException異常。
基於這種情況,我們通常新建一個線程進行網絡請求,比如一個如下的匿名類:
new Thread(new Runnable() {
@Override
public void run() {
}
}).start();
有些情況下我們希望在得到請求後進行相應的UI更新操作,這時我們又需要回到主線程更新UI,方法有很多,比如runOnUiThread、Handler、View.post、AsyncTask等,這裏我主要介紹第一種,同時也是比較推薦的。
runOnUiThread可以直接在Activity中調用,Fragment中需要在前面加上getActivity()
new Thread(new Runnable() {
@Override
public void run() {
// 進行網絡請求
runOnUiThread(new Runnable() {
@Override
public void run() {
// 更新UI
}
});
}
}).start();
另外我們有時希望寫一個循環在線程中每隔一段時間請求一次,並更新UI,但當這個Activity結束的時候我們希望能安全地關閉這個線程,所以while(true)是不合適也是不優雅的,當然while(flag)也是一個不錯的解決方式,但是這裏我想介紹另外一種方式,使用interrupt()
Thread thread;
thread = new Thread(new Runnable() {
@Override
public void run() {
while (!Thread.interrupted()) { // 非阻塞過程中通過判斷中斷標誌來退出
try {
// 進行網絡請求
runOnUiThread(new Runnable() {
@Override
public void run() {
// 更新UI
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break; // 阻塞過程捕獲中斷異常來退出,執行break跳出循環
}
}
}
});
thread.start();
然後重寫Activity的onDestroy方法,當Activity退出時終止線程
@Override
protected void onDestroy() {
super.onDestroy();
//被銷燬時終止線程
thread.interrupt();
}