在MainActivity中加载网络图片,代码如下:
public class NetImageActivity extends Activity {
String imageUrl = "http://s0.hao123img.com/res/img/moe/0328mh5.jpg";
Bitmap bmImg;
ImageView imView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imView = (ImageView) findViewById(R.id.imageViewId);
imView.setImageBitmap(returnBitMap(imageUrl));
}
public Bitmap returnBitMap(String url){
URL myFileUrl = null;
Bitmap bitmap = null;
try {
myFileUrl = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection conn = (HttpURLConnection) myFileUrl
.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
}
报错,信息如下
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
at java.net.InetAddress.getAllByName(InetAddress.java:214)
at com.android.okhttp.internal.Dns$1.getAllByName(Dns.java:28)
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:216)
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:122)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:292)
at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:89)
android.os.NetworkOnMainThreadException是说不要在主线程中访问网络,这个是android3.0版本开始就强制程序不能在主线程中访问网络,要把访问网络放在独立的线程中。
在开发中,为了防止访问网络阻塞主线程,一般都要把访问网络放在独立线程中或者异步线程AsyncTask中。
1、想要忽略这些强制策略问题的话,可以在onCreate()方法里面加上
StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
并在方法上加上@SuppressLint(“NewApi”),重试,OK。
2、将网络访问放到单独线程中:
public class NetImageActivity extends Activity {
String imageUrl = "http://content.52pk.com/files/100623/2230_102437_1_lit.jpg";
Bitmap bitmap;
ImageView imView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imView = (ImageView) findViewById(R.id.imageViewId);
Thread imageViewHander = new Thread(new NetImageHandler());
imageViewHander.start();
}
class NetImageHandler implements Runnable {
@Override
public void run() {
try {
URL url = new URL(imageUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
//发送消息,通知UI组件显示图片
handler.sendEmptyMessage(0);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what == 0){
imView.setImageBitmap(bitmap);
}
}
};
}
3、将网络访问放到异步任务AsyncTask中,代码如下:
public class NetImageActivity extends Activity {
String imageUrl = "http://content.52pk.com/files/100623/2230_102437_1_lit.jpg";
ImageView imView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imView = (ImageView) findViewById(R.id.imageViewId);
loadImage();
}
private void loadImage() {
new AsyncTask<String, Void, Bitmap>() {
//该方法运行在后台线程中,因此不能在该线程中更新UI,UI线程为主线程
@Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap = null;
try {
String url = params[0];
URL HttpURL = new URL(url);
HttpURLConnection conn = (HttpURLConnection) HttpURL.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
//在doInBackground 执行完成后,onPostExecute 方法将被UI 线程调用,
// 后台的计算结果将通过该方法传递到UI线程,并且在界面上展示给用户.
@Override
protected void onPostExecute(Bitmap bitmap) {
if(bitmap != null){
imView.setImageBitmap(bitmap);
}
}
}.execute(imageUrl);
}
}