Android:NetworkOnMainThreadException异常
看名字就应该知道,是网络请求在MainThread中产生的异常
从3.0开始,google不再允许网络请求(HTTP、Socket)等相关操作直接在Main Thread类中,其实本来就不应该这样做,直接在UI线程进行网络操作,会阻塞UI,导致用户体验较差。
解决办法
1.Handler消息机制
和network有关比较耗时的操作放到一个子线程里,然后用Handler消息机制与主线程通信
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.test);
new Thread(new Runnable() {
@Override
public void run() {
// TODO
// 在这里进行 http request.网络请求相关操作
Message msg = new Message();
Bundle data = new Bundle();
data.putString("value", "请求结果");
msg.setData(data);
handler.sendMessage(msg);
}
}).start(); // 开启一个子线程,进行网络操作,等待有返回结果,使用handler通知UI
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Bundle data = msg.getData();
String val = data.getString("value");
Log.i("mylog", "请求结果为-->" + val);
// TODO
// UI界面的更新等相关操作
}
};
2.AsyncTask
使用异步机制,如:asynctask,这个举个简单的加载网络图片的例子
class DownImage extends AsyncTask {
private ImageView imageView;
public DownImage(ImageView imageView) {
this.imageView = imageView;
}
@Override
protected Bitmap doInBackground(String... params) {
String url = params[0];
Bitmap bitmap = null;
try {
//加载一个网络图片
InputStream is = new URL(url).openStream();
bitmap = BitmapFactory.decodeStream(is);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}
}
3,直接在主线程中进行网络操作
在发起Http请求的Activity里面的onCreate函数里面添加如下代码(未测试):
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads().detectDiskWrites().detectNetwork()
.penaltyLog().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects().detectLeakedClosableObjects()
.penaltyLog().penaltyDeath().build());