0. 前言
#Android系統中主要提供了HttpURLConnection和HttpClient進行網路通信,但是如果不對其進行封裝#就很容易就會寫出重複程式碼。因此一些Android網路通訊框架應運而生, Volley就是其中的佼佼者,Volley不只可以進行HTTP通訊,也可以輕鬆載入網路上的圖片#。 Volley設計的初衷就是非常適合去進行資料量不大,但通訊頻繁的網路操作,而對於大數據量的網路操作,比如說下載檔等,Volley
的表現就會非常糟糕。原因總結如下:(1)Volley的網路請求執行緒池默認為4。因此只能並發進行4個請求(多了排隊),容易被4個較大文件的下載任務阻塞其餘請求
。(2)#Request的parseNetWorkResponse() 方法回傳byte[]類型#,需要把傳送到的資料讀到記憶體中。如果檔案過大,容易引發OOM
。
1. Volley的基本用途
1.1 HTTP GET請求
##首先在AS中導入Volley的jar套件。
RequestQueue mQueue = Volley.newRequestQueue(getApplicationContext()); StringRequest stringRequest_get = new StringRequest("http://www.baidu.com", new Response.Listener<String>() { @Override public void onResponse(String response) { Log.d("TAG", response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e("TAG", error.getMessage(), error); } }); mQueue.add(stringRequest);StringRequest
#的建構子需要傳入三個參數,第一個是URL
位址,第二
三個參數是伺服器回應成功/#失敗的回呼。若成功則將傳回的
html程式碼轉為String
#列印出
log
RequestQueue mQueue = Volley.newRequestQueue(getApplicationContext()); StringRequest stringRequest = new StringRequest(Method.POST, url, listener, errorListener) { @Override protected Map<String, String> getParams() throws AuthFailureError { Map<String, String> map = new HashMap<String, String>(); map.put("params1", "value1"); map.put("params2", "value2"); return map; } }; mQueue.add(stringRequest);##########
当发出POST请求的时候,Volley会尝试调用StringRequest的父类中的getParams()方法来获取POST参数,因此我们需要在StringRequest中重写getParams()方法,设置POST参数即可。
1.3 JsonRequest
和StringRequest一样,JsonRequest也是继承自Request类的, JsonRequest是一个抽象类,有两个子类JsonObjectRequest和JsonArrayRequest,前者用于请求一段JSON数据的,后者用于请求一段JSON数组。下面是使用前者进行一段Json请求的范例代码。
//队列初始化以及request加入队列略 JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { Log.d("TAG", response.toString()); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e("TAG", error.getMessage(), error); } });
1.4 ImageRequest
Volley支持对图片的加载,因为ImageRequest也是继承自Request类,因此用法也大同小异。下面直接传入图片url,返回数据后内部解析为bitmap,最后设置给ImageView。否则设置默认图片。
ImageRequest imageRequest = new ImageRequest(url_image, new Response.Listener<Bitmap>() { @Override public void onResponse(Bitmap response) { imageView.setImageBitmap(response); } }, 0, 0, Config.RGB_565, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { imageView.setImageResource(R.drawable.default_image); } });
需要注意的是,第三/四个参数用于指定允许图片最大的宽/高,若网络图片的实际宽高大于该设定值,则会对图片进行压缩,指定成0的话就表示不进行压缩。第五个参数用于指定图片的颜色属性,Bitmap.Config下的几个常量都可以在这里使用,其中ARGB_8888可以展示最好的颜色属性,每个图片像素占据4个字节的大小,而RGB_565则表示每个图片像素占据2个字节大小。不过这种加载图片的方式并不被推荐,因为下面有更好的。
1.5 ImageLoader
ImageLoader基于ImageRequest实现,并且更加智能,多出了帮图片缓存的功能,还可以过滤掉重复的请求链接。但是ImageLoader已经不再继承自Request类。
//mQueue初始化略 ImageLoader imageLoader = new ImageLoader(mQueue, new BitmapCache()); ImageListener listener = ImageLoader.getImageListener(imageView, R.drawable.default_image, R.drawable.failed_image); imageLoader.get(url_image, listener, 200, 200); //限制最大宽高 public class BitmapCache implements ImageCache { //内部使用LRU实现 private LruCache<String, Bitmap> mCache; public BitmapCache() { //缓存图片的大小设置为10M int maxSize = 10 * 1024 * 1024; mCache = new LruCache<String, Bitmap>(maxSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getRowBytes() * bitmap.getHeight(); } }; } @Override public Bitmap getBitmap(String url) { return mCache.get(url); } @Override public void putBitmap(String url, Bitmap bitmap) { mCache.put(url, bitmap); } }
第二行构造一个ImageLoader对象,其中第二个参数是一个ImageCache对象,参数二为自定义的用户缓存的类BitmapCache,该类继承了ImageCache。第三行获取一个ImageListener对象,传入参数比较简单,看名字就知道了。第四行调用ImageLoader的get()方法来加载图片。
1.6 NetworkImageView
这是第三种加载图片的方式,相对来说也是被用的比较多的方式。NetworkImageView继承自ImageView的,在原生的基础之上加入了加载网络图片的功能。用法仍旧是先创建一个RequestQueue对象和一个ImageLoader对象。接下来是在xml中定义我们的NetworkImageView,宽高表示裁剪到此宽高,wrap_content表示不裁剪。
<com.android.volley.toolbox.NetworkImageView android:id="@+id/network_image_view" android:layout_width="100dp" android:layout_height="100dp"/>
在Activity中获取到NetworkImageView实例后,就可以调用它的setDefaultImageResId()方法、setErrorImageResId()方法和setImageUrl()方法来分别设置加载时显示的图片,加载失败时显示的图片,以及目标图片的URL地址。
networkImageView.setDefaultImageResId(R.drawable.default_image); networkImageView.setErrorImageResId(R.drawable.failed_image); networkImageView.setImageUrl(url_image,imageLoader);
2. 自定义Request
在网络上传输的数据常用到XML和JSON格式,那么如果想要请求一条XML/JSON格式的数据就需要拓展我们的Volley。
2. 1 XMLRequest
public class StringRequest extends Request<String> { private final Listener<String> mListener; public StringRequest(int method, String url, Listener<String> listener, ErrorListener errorListener) { super(method, url, errorListener); mListener = listener; } public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) { this(Method.GET, url, listener, errorListener); } @Override protected void deliverResponse(String response) { mListener.onResponse(response); } @Override protected Response<String> parseNetworkResponse(NetworkResponse response) { String parsed; try { parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); } catch (UnsupportedEncodingException e) { parsed = new String(response.data); } return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response)); } }
拓展之前先要看一下原有的Request的子类是如何实现的,上面以StringRequest为例。StringRequest中提供了两个有参的构造函数,参数包括请求类型,请求地址,以及响应回调等,在构造函数中一定要调用super()方法将这几个参数传给父类,因为HTTP的请求和响应都是在父类中处理的。
由于Request类中的deliverResponse()和parseNetworkResponse()是两个抽象方法,因此StringRequest中对这两个方法进行了实现。前者调用了mListener中的onResponse()方法,并将response内容传入即完成了将服务器响应的数据进行回调。后者对服务器响应的数据进行解析,其中数据是以字节的形式存放在NetworkResponse的data变量中(前言中在Volley为什么不适合大文件下载就讲到了),这里将数据取出然后组装成一个String,并传入Response的success()方法中。
在了解了StringRequest之后,我们自定义实现我们的XMLRequest。
public class XMLRequest extends Request<XmlPullParser> { private final Listener<XmlPullParser> mListener; public XMLRequest(int method, String url, Listener<XmlPullParser> listener, ErrorListener errorListener) { super(method, url, errorListener); mListener = listener; } public XMLRequest(String url, Listener<XmlPullParser> listener, ErrorListener errorListener) { this(Method.GET, url, listener, errorListener); } @Override protected void deliverResponse(XmlPullParser response) { mListener.onResponse(response); } @Override protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) { try { //先转为字符串 String xmlString = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); //重点在于解析xml XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XmlPullParser xmlPullParser = factory.newPullParser(); xmlPullParser.setInput(new StringReader(xmlString)); //返回XmlPullParser实例 return Response.success(xmlPullParser, HttpHeaderParser.parseCacheHeaders(response)); } catch (UnsupportedEncodingException e) { return Response.error(new ParseError(e)); } catch (XmlPullParserException e) { return Response.error(new ParseError(e)); } } } //使用我们的XMLRequest XMLRequest xmlRequest = new XMLRequest( url_xml, new Response.Listener<XmlPullParser>() { @Override public void onResponse(XmlPullParser response) { try { int eventType = response.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_TAG: String nodeName = response.getName(); if (WANTED_TAG.equals(nodeName)) { String pName = response.getAttributeValue(0); Log.d("TAG", "pName is " + pName); } break; } eventType = response.next(); } } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e("TAG", error.getMessage(), error); } });
2. 2 GsonRequest
用过Gson的都知道Gson解析有多方便,这里可以把Volley和Gson结合在一起吗?当然可以。重写代码基本上大同小异。前提是先导入Gson的jar包。
public class GsonRequest<T> extends Request<T> { private final Listener<T> mListener; private Gson mGson; private Class<T> mClass; public GsonRequest(int method, String url, Class<T> clazz, Listener<T> listener, ErrorListener errorListener) { super(method, url, errorListener); mGson = new Gson(); mClass = clazz; mListener = listener; } public GsonRequest(String url, Class<T> clazz, Listener<T> listener, ErrorListener errorListener) { this(Method.GET, url, clazz, listener, errorListener); } @Override protected Response<T> parseNetworkResponse(NetworkResponse response) { try { String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); //结合Gson解析 return Response.success(mGson.fromJson(jsonString, mClass), HttpHeaderParser.parseCacheHeaders(response)); } catch (UnsupportedEncodingException e) { return Response.error(new ParseError(e)); } } @Override protected void deliverResponse(T response) { mListener.onResponse(response); } } //使用我们的GsonRequest GsonRequest<Weather> gsonRequest = new GsonRequest<Weather>(url_json,YourClass.class, new Response.Listener<Weather>() { @Override public void onResponse(YourClass obj) { //这里获得obj对应的json中的数据 } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e("TAG", error.getMessage(), error); } });
以上是Android開發—Volley具體的使用詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

WebStorm Mac版
好用的JavaScript開發工具

禪工作室 13.0.1
強大的PHP整合開發環境

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver CS6
視覺化網頁開發工具