这段时间在做客户端,用的是2.3的模拟器,一直没注意做网络请求时的延时问题(因为在本地),今天放到4.0版本的真机上做测试,结果用不了,DEBUG一下:
05-19 14:40:09.432: W/HttpUtils(1274): Exception =null
05-19 14:40:09.432: W/System.err(1274): android.os.NetworkOnMainThreadException
05-19 14:40:09.477: W/System.err(1274): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
05-19 14:40:09.482: W/System.err(1274): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
05-19 14:40:09.482: W/System.err(1274): at libcore.io.IoBridge.connectErrno(IoBridge.java:144)
05-19 14:40:09.482: W/System.err(1274): at libcore.io.IoBridge.connect(IoBridge.java:112)
05-19 14:40:09.493: W/System.err(1274): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
05-19 14:40:09.512: W/System.err(1274): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
05-19 14:40:09.512: W/System.err(1274): at java.net.Socket.connect(Socket.java:842)
05-19 14:40:09.512: W/System.err(1274): at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
...
网上找解决办法:http://www.2cto.com/kf/201402/281526.html
一个APP如果在主线程中请求网络操作,将会抛出此异常。Android这个设计是为了防止网络请求时间过长而导致界面假死的情况发生。
解决方案有两个,一个是使用StrictMode,二是使用线程来操作网络请求。
第一种方法:简单暴力,强制使用,代码修改简单(但是非常不推荐)
在MainActivity文件的setContentView(R.layout.activity_main)下面加上如下代码
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
第二种方法就是我使用的方法也是我要推荐的方法,将请求网络资源的代码使用Thread去操作。在Runnable中做HTTP请求,不用阻塞UI线程。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main_view);
new Thread(runnable).start();
}
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Bundle data = msg.getData();
String val = data.getString("value");
Log.i(TAG,"请求结果:" + val);
}
}
Runnable runnable = 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);
}
}
上面是比较通用的方法,我的代码:
// Android 4.0 之后不能在主线程中请求HTTP请求
new Thread(new Runnable(){
@Override
public void run() {
cachedImage = asyncImageLoader.loadDrawable(imageUrl, position);
imageView.setImageDrawable(cachedImage);
}
}).start();