众所周知,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();
}