在Android中,如果我們要展示的圖片是儲存在網路上的時候,我們就必須通過HttpClient或者HttpUrlConnection這兩個類來進行關於網路方面的操作,比如下面中利用GridView來展示幾個圖片:
關於GridView如何來展示圖片就不多講了,這個其實是跟ListView利用BaseAdapter來展示的原理是一樣的,大家有興趣可以下面的文章看一下:
Android中關於Adapter的使用(下)BaseAdapter
<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+1NrV4sDvo6zO0sPHz8i/tNK7z8LU9cO0wPvTw0h0dHBVcmxDb25uZWN0aW9uwLS78cihzfjC58nPtcTNvMastcShozwvcD4KPHA+MaOpytfPyMrHzbzGrNS0o7o8L3A+CjxwPjxwcmUgY2xhc3M9"brush:java;">private static final String[] URLS = {"http://img.my.csdn.net/uploads/201403/03/1393854094_4652.jpg","http://img.my.csdn.net/uploads/201403/03/1393854084_6138.jpg","http://img.my.csdn.net/uploads/201403/03/1393854084_1323.jpg","http://img.my.csdn.net/uploads/201403/03/1393854084_8439.jpg","http://img.my.csdn.net/uploads/201403/03/1393854083_6511.jpg","http://img.my.csdn.net/uploads/201403/03/1393854083_2323.jpg"};private static final String[] DESCS = {"photo1","photo2","photo3","photo4","photo5","photo6"};
2)在BaseAdapter的getView方法中,我們要去擷取網路上的圖片,並將其轉化為Bitmap,代碼如下:
viewHolder.ivImage.setImageBitmap(readBitmapFromUrl(URLS[position]));...public Bitmap readBitmapFromUrl(String imgUrl){BitmapFactory.Options op = new BitmapFactory.Options();op.inPreferredConfig = Bitmap.Config.ARGB_8888;op.inDither = false;op.inScaled = false;Bitmap bitmap = null;try {URL url = new URL(imgUrl);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(3 * 1000);if(conn.getResponseCode() != 200){ throw new RuntimeException("Request Failed");}InputStream is = conn.getInputStream();bitmap = BitmapFactory.decodeStream(is,null,op);bitmap = Helper.zoomBitmap(bitmap, 150, 150);} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return bitmap;}在這裡,我們首先根據參數imgUrl定義了URL對象,並通過openConnection函數返回HttpURLConnection對象,然後利用BitmapFactory的decodeStream方法將Response的stream給解析成對應的Bitmap,而擷取到的圖片可能是比較大的,我們需要將其縮小到適合的大小,以便在螢幕上顯示,於是我們又調用了zoomBitamp函數(自訂的函數)來進行一個縮小的操作。
我們會發現,雖然我們能夠利用HttpURLConnection這樣去實現我們想要的功能,但是需要我們自己去做的事情還是太多了,尤其是在上面還沒有考慮圖片非常多的情況,沒有考慮緩衝,網路請求等方面的因素,真的要去考慮,會煩死的。
而且上面的代碼只是適宜運行在2.3以上,4.0以下的機器,在4.0以上的機器,是不允許我們直接這樣去用HttpURLConnection來進行網路方面的通訊的,會爆下面的錯誤的,如下:
03-04 23:18:44.773: E/AndroidRuntime(13299): android.os.NetworkOnMainThreadException 03-04 23:18:44.773: E/AndroidRuntime(13299): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1103) 03-04 23:18:44.773: E/AndroidRuntime(13299): at java.net.InetAddress.lookupHostByName(InetAddress.java:391) 03-04 23:18:44.773: E/AndroidRuntime(13299): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242) 03-04 23:18:44.773: E/AndroidRuntime(13299): at java.net.InetAddress.getAllByName(InetAddress.java:220) 03-04 23:18:44.773: E/AndroidRuntime(13299): at libcore.net.http.HttpConnection.(HttpConnection.java:71) 03-04 23:18:44.773: E/AndroidRuntime(13299): at libcore.net.http.HttpConnection.(HttpConnection.java:50) 03-04 23:18:44.773: E/AndroidRuntime(13299): at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351) 03-04 23:18:44.773: E/AndroidRuntime(13299): at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86) 03-04 23:18:44.773: E/AndroidRuntime(13299): at libcore.net.http.HttpConnection.connect(HttpConnection.java:128) 03-04 23:18:44.773: E/AndroidRuntime(13299): at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308) 03-04 23:18:44.773: E/AndroidRuntime(13299): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:460) 03-04 23:18:44.773: E/AndroidRuntime(13299): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:432)
我覺得開發的,就要善於去利用各種各樣的工具來減輕我們的時間成本,而Volley就是Android中一個很好的網路通訊的小工具啦,雖然我們自己封裝一下,也能夠做到同樣的功能,但是有時候,人與人之間的的差別還真是在那裡的,有些人就能夠做得很好,而有些人就真的做不到那麼好,跑題了,只是感歎一下牛人的世界。
那麼如何利用Volley來實現網狀圖片的載入呢?其實有很多種方式的,今天我們就先講一種最簡單的載入方式,代碼如下:
1)定義一個RequestQueue,如下:
private RequestQueue mQueue;
2)在OnCreate方法中對其進行初始化,this其實就是當前Activity,是一個Context類:
mQueue = Volley.newRequestQueue(this);
3)建立ImageRequest對象,並將其添加到mQueue中,如下:
public void readBitmapViaVolley(String imgUrl, final ImageView imageView) {ImageRequest imgRequest = new ImageRequest(imgUrl,new Response.Listener() {@Overridepublic void onResponse(Bitmap arg0) {// TODO Auto-generated method stubimageView.setImageBitmap(arg0);}}, 300, 200, Config.ARGB_8888, new ErrorListener() {@Overridepublic void onErrorResponse(VolleyError arg0) {}});mQueue.add(imgRequest);}在上面,我們可以看到,在ImageRequest的建構函式中,我們就可以直接將一些關於Bitmap的參數給傳進去了,比如長寬等資訊,然後在其返回的Response.Listener中獲得返回的結果,就是一個Bitmap了,並在onResponse函數中對ImageView進行設定,最後將其添加到mQueue中。
4)當上面的一切都做好之後,就可以了,實現的效果跟我們利用HttpURLConnection來實現的效果是一模一樣的,而且更快,代碼也簡潔很多,是不?
Volley的功能不僅僅是這樣簡單地用簡潔的代碼來幫我們封裝函數,也不僅僅只是操作圖片,在其隱藏在後面的代碼中,還做了其它一些工作,比如:
1)緩衝的使用,包括記憶體和SD卡
2)網路請求隊列的處理跟最佳化
3)圖片載入的最佳化
4)對JSON資料的最佳化等
後面有時間,大家一起來學習學習吧。