很多教程上有關網路訪問的程式碼,最簡單的有類似這樣的:
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進行執行緒策略規劃