在MainActivity中加載網絡圖片,代碼以下:
java
public class NetImageActivity extends Activity { String imageUrl = "http://content.52pk.com/files/100623/2230_102437_1_lit.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; } }
報錯,信息以下
android
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中。異步
一、想要忽略這些強制策略問題的話,能夠在onCreate()方法裏面加上ide
StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy);
並在方法上加上@SuppressLint("NewApi"),重試,OK。ui
二、將網絡訪問放到單獨線程中: url
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); } } }; }
三、將網絡訪問放到異步任務AsyncTask中,代碼以下: spa
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); } }