很多教程上有关网络访问的代码,最简单的有类似这样的:
ImageView imgV = (ImageView) findViewById(R.id.imageView1);
try {
URL url = new URL("http://url地址");
InputStream is = url.openStream();
Bitmap bm = BitmapFactory.decodeStream(is);
imgV.setImageBitmap(bm);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
但是就是这个如此简单的代码也可能让你折腾死,报android.os.NetworkOnMainThreadException异常无法运行。这个异常大概意思是在主线程访问网络时出的异常。 Android在4.0之前的版本支持在主线程中访问网络,但是在4.0以后对这部分程序进行了优化,也就是说访问网络的代码不能写在主线程中了。
解决方法:多线程,异步加载的方式加载数据
具体方法就是各种多线程/异步的实现,如下述方法之一。
new Thread() {
@Override
public void run() {
// 需要执行的方法
// 执行完毕后给handler发送一个空消息
handler.sendEmptyMessage(0);
}
}.start();
//定义Handler对象
private Handler handler = new Handler() {
//当有消息发送出来的时候就执行Handler的这个方法来处理消息分发
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//处理UI
}
};
也可以用AsyncTask来实现
class DownImage extends AsyncTask {
private ImageView imageView;
public DownImage(ImageView imageView) {
//TODO Auto-generated method stub
this.imageView = imageView;
}
@Override
protected Bitmap doInBackground(String... params) {
//TODO Auto-generated method stub
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) {
//TODO Auto-generated method stub
imageView.setImageBitmap(result);
}
}
还有可以用StrictMode进行线程策略规划
|