最近在看網絡通訊這塊時,頻繁的使用到Http通訊,而Android系統中主要提供兩種方式來進行Http通訊,HttpURLConnection和HttpClient。不過在實際使用在仍是有點麻煩和複雜的。常常一不當心就出錯,在羣裏看到有人推薦使用Valley,對齊進行了很好的封裝,簡單方便。
Volley是2013 GoogleI/O大會上推出的網絡通訊框架,因此在性能方面是毋庸置疑的。下面算是總結一下本身對於Volley的學習筆記吧。 html
下載Volleynode
若是你的電腦上裝有Git,能夠使用以下命令下載Volley的源碼:android
1 git clone https://android.googlesource.com/platform/frameworks/volley
這裏放出部分功能看看:git
準備工做作好之後就開始正式用了,我這裏只以Http通訊來介紹,其餘的也須要進一步去了解了。服務器
1.StringRequest網絡
1.首先的獲取到一個RequestQueue對象 框架
1 RequestQueue mQueue= Volley.newRequestQueue(context);
2.發送一條Http請求,咱們須要建立一個StringRequest對象:ide
1 StringRequest stringRequest=new StringRequest("http://www.baidu.com", new Response.Listener<String>() { 2 @Override 3 public void onResponse(String s) { 4 Log.d(TAG, "onResponse: "+s); 5 } 6 }, new Response.ErrorListener() { 7 @Override 8 public void onErrorResponse(VolleyError volleyError) { 9 Log.e(TAG,volleyError.getMessage(),volleyError); 10 } 11 });
這裏StringRequest裏面須要傳入三個參數:第一個參數是目標url地址,第二個是服務器響應成功的的回調,第三個是服務器響應失敗的回調。我這裏就用log代替具體回調內容。
3.將這個stringRequest添加到RequestQueue裏面:函數
1 mQueue.add(stringRequest);
打開LogCat就會看到下面這樣:佈局
至於內容我就先不去管那麼多了。可以獲得結果就證實沒錯了。前面用到的只是Get請求,若是你想使用Post則須要添加參數來指定請求類型,以下:
1 StringRequest stringRequest=new StringRequest(Request.Method.POST,"http://www.baidu.com",listener,erroelistener)
這裏還只是指定了請求類型若是須要提交給服務器仍是不行的,還須要重寫getParams()方法,以下:
簡單來講,就是三步操做:
1.建立一個RequestQueue對象。
2.建立一個StringRequest對象。
3.將StringRequest對象添加到RequestQueue裏面。
由於Volley是開源,若是不知足如今的使用,你大能夠本身添加或者修改本身想要的方法。一樣的JsonRequest和JsonObjectRequest還有ImageRequest用法是相同的,想了解的能夠本身實踐。
2.ImageLoader
1. 建立一個RequestQueue對象:
1 RequestQueue mQueue= Volley.newRequestQueue(context);
2.建立一個ImageLoader對象:
1 ImageLoader imageLoader=new ImageLoader(mQueue,bitmapCache);
這裏第一個參數爲一個RequestQueue對象,第二個參數爲ImageCache對象。下面會貼出bitmapCache代碼
3.調用ImageLoader的get()方法加載圖片:
1 imageLoader.get("http://images.cnblogs.com/cnblogs_com/yeshuwei/837768/o_u=733417015,367501698_fm=11_gp=0.jpg",listener);
這裏第一個參數爲圖片的Url地址,第二個參數爲一個ImageListener對象,能夠經過以下獲取:
ImageLoader.ImageListener listener=imageLoader.getImageListener(imageView,R.mipmap.defaulting,R.mipmap.error);
第一個參數用於指定顯示圖片的ImageView空間,第二個圖片爲加載時顯示的圖片,第三個爲加載錯誤時候顯示的圖片。
你也能夠經過在get()方法中指定圖片的高度和寬度:
1 imageLoader.get("http://images.cnblogs.com/cnblogs_com/yeshuwei/837768/o_u=733417015,367501698_fm=11_gp=0.jpg",
2 listener, 200, 200);
BitmapCache代碼:
1 public class BitmapCache implements ImageLoader.ImageCache { 2 private LruCache<String, Bitmap> mCache; 3 4 public BitmapCache() { 5 int maxSize = 10 * 1024 * 1024; 6 mCache = new LruCache<String, Bitmap>(maxSize) { 7 @Override 8 protected int sizeOf(String key, Bitmap bitmap) { 9 return bitmap.getRowBytes() * bitmap.getHeight(); 10 } 11 }; 12 } 13 14 @Override 15 public Bitmap getBitmap(String url) { 16 return mCache.get(url); 17 } 18 19 @Override 20 public void putBitmap(String url, Bitmap bitmap) { 21 mCache.put(url, bitmap); 22 } 23 }
ImageLoader就學習到這裏了。
3.NetworkImageView
NetworkImageview是一種自定義控件用來加載圖片,使用方法以下:
1.建立一個RequestQueue對象
2.在佈局文件中加載一個NetworkImageView控件
3.建立一個ImageLoader對象
4.在代碼中獲取NetworkImageView控件的實例
5.設置要加載的圖片
1 bitmapCache=new BitmapCache(); 2 networkImageView= (NetworkImageView) findViewById(R.id.network_image_view); 3 RequestQueue mQueue= Volley.newRequestQueue(context); 4 ImageLoader imageLoader=new ImageLoader(mQueue,bitmapCache); 5 networkImageView.setDefaultImageResId(R.mipmap.defaulting);//加載中顯示的圖片 6 networkImageView.setErrorImageResId(R.mipmap.error);//加載錯誤時顯示的圖片 7 networkImageView.setImageUrl("http://images.cnblogs.com/cnblogs_com/yeshuwei/837768/o_u=733417015,367501698_fm=11_gp=0.jpg",imageLoader);
setImageUrl接收兩個參數,第一個是圖片的Url地址,第二個爲ImageLoader對象。
關於圖片加載的目前就學到ImageRequest,ImageLoader,NetworkImageView三種。接下來說講自定義的Volley
4.XMLRequest
這裏根據郭神的博客跟着學習了一下如何自定義的使用Volley,這裏來自頂一個XMLRequest來解析一條XML格式的數據。
打開StringRequest和JsonRequest的源碼發現都是繼承自Request的而且Request是可以制定泛型類的,這樣就能很好的擴張咱們想要的東西了。
而後提供了兩個有參數的構造方法和兩個要重寫的抽象方法。這裏貼一下源碼:
1 public class StringRequest extends Request<String> { 2 private final Listener<String> mListener; 3 4 public StringRequest(int method, String url, Listener<String> listener, ErrorListener errorListener) { 5 super(method, url, errorListener); 6 this.mListener = listener; 7 } 8 9 public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) { 10 this(0, url, listener, errorListener); 11 } 12 13 protected void deliverResponse(String response) { 14 this.mListener.onResponse(response); 15 } 16 17 protected Response<String> parseNetworkResponse(NetworkResponse response) { 18 String parsed; 19 try { 20 parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); 21 } catch (UnsupportedEncodingException var4) { 22 parsed = new String(response.data); 23 } 24 25 return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response)); 26 } 27 }
須要注意的是,在構造函數中必定要調用super()方法將這幾個參數傳給父類,由於HTTP的請求和響應都是在父類中自動處理的。deliverResponse()方法中的實現很簡單,僅僅是調用了mListener中的onResponse()方法,並將response內容傳入便可,這樣就能夠將服務器響應的數據進行回調了。parseNetworkResponse()方法中則應該對服務器響應的數據進行解析,其中數據是以字節的形式存放在NetworkResponse的data變量中的,這裏將數據取出而後組裝成一個String,並傳入Response的success()方法中便可。
詳情參考郭神博客:http://blog.csdn.net/guolin_blog/article/details/17612763
下面動手來跟着郭神試試手。
1 public class XMLRequest extends Request<XmlPullParser> { 2 private final Response.Listener<XmlPullParser> mListener; 3 4 public XMLRequest(int method, String url,Response.Listener<XmlPullParser> listener, 5 Response.ErrorListener errorListener) { 6 super(method, url, errorListener); 7 this.mListener = listener; 8 } 9 public XMLRequest(String url, Response.Listener<XmlPullParser> listener, Response.ErrorListener errorListener) { 10 this(Method.GET, url, listener, errorListener); 11 } 12 13 14 /*parseNetworkResponse()方法中則應該對服務器響應的數據進行解析, 15 其中數據是以字節的形式存放在NetworkResponse的data變量中的, 16 這裏將數據取出而後組裝成一個String,並傳入Response的success()方法中便可。*/ 17 @Override 18 protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) { 19 try { 20 String xmlString=new String(response.data, HttpHeaderParser.parseCharset(response.headers)); 21 XmlPullParserFactory factory=XmlPullParserFactory.newInstance(); 22 XmlPullParser parser=factory.newPullParser(); 23 parser.setInput(new StringReader(xmlString)); 24 return Response.success(parser, HttpHeaderParser.parseCacheHeaders(response)); 25 } catch (UnsupportedEncodingException e) { 26 return Response.error(new ParseError(e)); 27 }catch (XmlPullParserException e) { 28 return Response.error(new ParseError(e)); 29 } 30 31 } 32 /*deliverResponse()方法中的實現很簡單,僅僅是調用了mListener中的onResponse()方法, 33 並將response內容傳入便可,這樣就能夠將服務器響應的數據進行回調了。*/ 34 @Override 35 protected void deliverResponse(XmlPullParser xmlPullParser) { 36 mListener.onResponse(xmlPullParser); 37 } 38 }
下面來嘗試用這個XMLRequest來請求一段XML數據
1 public class xmlRequest extends AppCompatActivity { 2 private Context context; 3 private static final String TAG = "xmlRequest"; 4 @Override 5 protected void onCreate(@Nullable Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 context=getApplicationContext(); 8 RequestQueue mQueue= Volley.newRequestQueue(context); 9 XMLRequest xmlr=new XMLRequest("http://flash.weather.com.cn/wmaps/xml/china.xml", new Response.Listener<XmlPullParser>() { 10 @Override 11 public void onResponse(XmlPullParser xmlPullParser) { 12 try { 13 int eventType=xmlPullParser.getEventType(); 14 while (eventType!=XmlPullParser.END_DOCUMENT){ 15 switch (eventType){ 16 case XmlPullParser.START_TAG: 17 String nodename=xmlPullParser.getName(); 18 if ("city".equals(nodename)){ 19 String pName=xmlPullParser.getAttributeValue(0); 20 Log.d(TAG, "pName is " + pName); 21 } 22 break; 23 } 24 try { 25 eventType=xmlPullParser.next(); 26 } catch (IOException e) { 27 e.printStackTrace(); 28 } 29 } 30 } catch (XmlPullParserException e) { 31 e.printStackTrace(); 32 } 33 } 34 }, new Response.ErrorListener() { 35 @Override 36 public void onErrorResponse(VolleyError volleyError) { 37 Log.e(TAG, volleyError.getMessage(),volleyError ); 38 } 39 }); 40 mQueue.add(xmlr); 41 } 42 }
其中http://flash.weather.com.cn/wmaps/xml/china.xml是一個用來以XMl格式還回中國因此省份數據的接口。
目前所學就這麼些了,參考資料以下:
1.慕課網視頻:http://www.imooc.com/learn/468
2.郭神博客:http://blog.csdn.net/guolin_blog?viewmode=contents
3.菜鳥驛站小豬關於XML數據解析講解:http://www.runoob.com/w3cnote/android-tutorial-xml.html
RequestQueue mQueue= Volley.newRequestQueue(context);