Android Volley 詳解 Google釋出的一套用於網路通訊的工具庫
下載地址:git clone https://android.googlesource.com/platform/frameworks/volley
或 : https://github.com/mcxiaoke/android-volley
Volley 能作什麼
Google 2013 I/O 大會上釋出的一個網路通訊庫。處理一些網路方面的請求,如資料解析、下載顯示圖片。
· 資料處理:對網路請求獲取的資料的處理。
· 圖片載入:對網路圖片的下載及顯示。
使用步驟
使用許可權
<uses-permissionandroid:name="android.permission.INTERNET"/>
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
初始化請求佇列
RequestQueue mRequestQueue = Volley.newRequestQueue(Context context);
網路請求資料處理
預設提供兩種資料請求型別,一為StringRequest,一為JsonRequest
JsonRequest又分:
· JsonArrayRequest
JsonArrayRequest request = new JsonArrayRequest("url", new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray response) {//請求響應返回的JSONArray } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { } }); mRequestQueue.add(request);
· JsonObjectRequest
mRequestQueue.add(request); 將請求加入佇列。 可以有很多個add 入隊操作,然後startJsonObjectRequest request = new JsonObjectRequest(Method.GET, WEATHER_JSON_ADDRESS, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) {//請求響應返回的JSONObject System.out.println(response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { System.out.println("test4JsonObjectRequest - error"); } }); mRequestQueue.add(request);
mRequestQueue.start(); 啟動請求
mRequestQueue.stop(); 停止請求
圖片載入請求
· ImageRequest 載入圖片
使用方式與上面的JsonRequest類似
private void requestByImageRequest(final ImageView imageView, String url) {
ImageRequest imgRequest = new ImageRequest(url,
new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap bitmap) {//下載成功後
imageView.setImageBitmap(bitmap);
}
},
imageView.getWidth(), imageView.getHeight(), Config.RGB_565,
new ErrorListener(){
@Override
public void onErrorResponse(VolleyError error) { //下載出錯
}
});
mRequestQueue.add(imgRequest);
mRequestQueue.start();
}
· ImageLoader 載入圖片
private void requestByImageLoader(ImageView imageView, String url) {
int maxMemory = (int) Runtime.getRuntime().maxMemory();//app最大記憶體 位元組數
int mCacheSize = maxMemory / 8; //以1/8 用作快取
final LruCache<String, Bitmap> mLruImageCache = new LruCache<String, Bitmap>(mCacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {//計算一張圖片的記憶體size
if (android.os.Build.VERSION.SDK_INT >= 12) {
return value.getByteCount(); //需要api >=12 , 總位元組數
} else {
return value.getRowBytes() * value.getHeight(); //每行位元組乘以高(即行) api1
}
}
};
ImageCache imageCache = new ImageCache() {
@Override
public void putBitmap(String key, Bitmap value) {
mLruImageCache.put(key, value);
}
@Override
public Bitmap getBitmap(String key) {
return mLruImageCache.get(key);
}
};
ImageLoader mImageLoader = new ImageLoader(mRequestQueue, imageCache);
// ImageLoader.getImageListener的第二個引數是預設的圖片resource id,請求的圖片為空時設定
// 第三個引數是請求失敗時候的資源id,可以指定為0
ImageListener listener = ImageLoader.getImageListener(
imageView, android.R.drawable.ic_menu_rotate,
android.R.drawable.ic_delete);
mImageLoader.get(url, listener); //get方法已經開始執行了載入url-bitmap
// ImageContainer imageContainer = mImageLoader.get(url, listener); //get方法已經開始執行了載入url-bitmap
// Bitmap bitmap = imageContainer.getBitmap();
// String requestUrl = imageContainer.getRequestUrl();
}
ImageLoader 需要結合 ImageCache來進行構造。ImageCache是一個interface
ImageCache 的put/get Bitmap的方法 ,推薦使用LruCache來實現。
ImageListener 是一個interface,提供兩個方法:onResponse(),onResponseError()
ImageLoader 圖片載入流程:ImageLoader.get(url, listener),判斷是否存在於cache中,如果有,則直接取出並在listener中顯示;如果沒有,則new
一個ImageRequest,加入到requestQueue中,將listener中相應的方法在ImageRequest中的Response.Listener中進行呼叫。
· NetworkImageView 載入圖片
private void requestByNetworkImg(NetworkImageView imageView, String url) {
final LruCache<String, Bitmap> mImageCache = new LruCache<String, Bitmap>(8*1024*1024) {
@Override
protected int sizeOf(String key, Bitmap value) {//計算一張圖片的記憶體size
return value.getRowBytes() * value.getHeight(); //每行位元組乘以高(即行) api1
}
};
ImageCache imageCache = new ImageCache() {
@Override
public void putBitmap(String key, Bitmap value) {
mImageCache.put(key, value);
}
@Override
public Bitmap getBitmap(String key) {
return mImageCache.get(key);
}
};
ImageLoader mImageLoader = new ImageLoader(mRequestQueue, imageCache);
/*
* seturl時,裡面的實現是:有了ImageLoader,就能執行載入url-bitmap的操作
*/
imageView.setDefaultImageResId(0); //預設圖
imageView.setErrorImageResId(0); //錯誤圖
imageView.setImageUrl(url, mImageLoader);
}
這是一個繼承自ImageView的自定義元件。
imageView.setDefaultImageResId(0); //預設圖
imageView.setErrorImageResId(0); //錯誤圖
imageView.setImageUrl(url, mImageLoader);
結合了ImageLoader,內部呼叫ImageLoader.get()來實現圖片的載入。
在ListView中的item使用NetworkImageView:
只需要new 一個ImageLoader物件。不同的item,set不同的URL即可。
因為在ImageLoader中會new不同的ImageRequest加到RequestQueue中執行下載。
自定義Request
/**
* Volley adapter for JSON requests that will be parsed into Java objects by Gson.
*/
public class GsonObjectRequest<T> extends Request<T> {
protected final Gson gson = new Gson();
protected final Class<T> clazz;
protected final Map<String, String> headers;
protected final Listener<T> listener;
/**
* Make a GET request and return a parsed object from JSON.
*
* @param url URL of the request to make
* @param clazz Relevant class object, for Gson's reflection
* @param headers Map of request headers
*/
public GsonObjectRequest(int method, String url, Class<T> clazz, Map<String, String> headers,
Listener<T> listener, ErrorListener errorListener) {
super(method, url, errorListener);
this.clazz = clazz;
this.headers = headers;
this.listener = listener;
}
public GsonObjectRequest(String url, Class<T> clazz, Map<String, String> headers,
Listener<T> listener, ErrorListener errorListener) {
this(Method.GET, url, clazz, headers, listener, errorListener);
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
//將請求獲取的json轉成 用gson 轉成了對應的物件
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(
response.data, HttpHeaderParser.parseCharset(response.headers));
return Response.success(
gson.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
}
自定義Request,至少需要重寫 parseNetworkResponse() 、deliverResponse()其他說明
Volley 類中定義了磁碟快取目錄。
Request .cancel() ,可以取消一個請求。
Request .setTag(String tag),設定一個tag
RequestQueue .cancelAll(String tag),取消同一tag標識的Request
RequestQueue .cancelAll(new RequestFilter() {}); 以RequestFilter來過濾 需要取消的Request