1. 程式人生 > >Android Volley框架詳解

Android Volley框架詳解

注:文章出自http://blog.csdn.net/guolin_blog/article/details/17482095,有興趣可以先去閱讀。

Volley簡介

對於Android系統網路通訊,我們知道目前用的最普遍的就是HttpClient和HttpURLConnection,但是HttpURLConnection和HttpClient的用法還是稍微有些複雜的,需要我們去封裝程式碼,減少冗餘度。Google開發團隊也看到了這個問題,所以在2013年Google I/O大會上推出了一個新的網路通訊框架——Volley,Volley集成了AsyncHttpClient框架和Universal-Image-Loader為一體,在效能方面也進行了大幅度的調整,非常適合去進行資料量不大,但通訊頻繁的網路操作。


Volley下載

①.如果你的電腦安裝過git,請使用如下命令

git clone https://android.googlesource.com/platform/frameworks/volley  

②.如果你的電腦沒安裝git,請到此地址下載

Volley使用流程

 ①.建立RequestQueue物件
 ②.建立Request物件
 ③.將Request物件加入RequestQueue

Volley自帶請求

 1.StringRequest ---請求字串

private void requestStringData() {
	RequestQueue mRequestQueue = Volley.newRequestQueue(this);
	// 指定請求方式,攜帶請求引數
	StringRequest mRequest = new StringRequest(Method.POST, "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.d(TAG, error.getMessage(), error);
		}
	}

	) {
		@Override
		protected Map<String, String> getParams() throws AuthFailureError {
			Map<String, String> mParams = new HashMap<String, String>();
			mParams.put("params1", "value1");
			mParams.put("params2", "value2");
			return mParams;
		}
	};
	mRequestQueue.add(mRequest);
}

除了我們上面講到的Volley處理流程之外,如果要新增請求引數的話,我們可以去重寫它的getParams方法。

2.JsonRequest ---請求Json物件

private void requestJosnObjectData() {
	RequestQueue mRequestQueue = Volley.newRequestQueue(this);
	JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("http://m.weather.com.cn/data/101010100.html", 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);
		}
	});
	mRequestQueue.add(jsonObjectRequest);
}

3.JsonArrayRequest ---請求json陣列

 略

4.ImageRequest ---請求圖片(1)

private void showImage() {
	RequestQueue mRequestQueue = Volley.newRequestQueue(this);
	ImageRequest mImageRequest = new ImageRequest("http://www.baidu.com/img/bdlogo.png", 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) {
			Log.i(TAG, error.getMessage(), error);
		}
	});
	mRequestQueue.add(mImageRequest);
}

5.ImageLoader ---請求圖片(2)

private void showImage2() {
	networkImageView.setVisibility(View.GONE);
	// 1. 建立一個RequestQueue物件。
	RequestQueue mRequestQueue = Volley.newRequestQueue(this);
	// 2. 建立一個ImageLoader物件。
	ImageLoader mImageLoader = new ImageLoader(mRequestQueue, new BitmapCache());
	// 3. 獲取一個ImageListener物件。
	ImageListener imageListener = ImageLoader.getImageListener(imageView, R.drawable.image_default, R.drawable.image_error);
	// 4. 呼叫ImageLoader的get()方法載入網路上的圖片。
	//mImageLoader.get("http://www.baidu.com/img/bdlogo.png", imageListener);
	mImageLoader.get("http://www.baidu.com/img/bdlogo.png", imageListener, 200, 200);
}

6.NetworkImageView ---請求圖片(3)

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/iv_network"
        android:layout_width="200dp"
        android:layout_height="200dp" >
    </com.android.volley.toolbox.NetworkImageView>
private void showImage3() {
	imageView.setVisibility(View.GONE);
	//1. 建立一個RequestQueue物件。
	RequestQueue mRequestQueue = Volley.newRequestQueue(this);
	//2. 建立一個ImageLoader物件。
	ImageLoader mImageLoader = new ImageLoader(mRequestQueue, new BitmapCache());
	//3. 在佈局檔案中新增一個NetworkImageView控制元件。
	//4. 在程式碼中獲取該控制元件的例項。
	//5. 設定要載入的圖片地址。
	networkImageView.setDefaultImageResId(R.drawable.image_default);
	networkImageView.setErrorImageResId(R.drawable.image_error);
	networkImageView.setImageUrl("http://www.baidu.com/img/bdlogo.png", mImageLoader);
}

指定自己的Volley請求(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 Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) {
		try {
			String xmlString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
			XmlPullParser xmlPullParser = Xml.newPullParser();
			xmlPullParser.setInput(new StringReader(xmlString));
			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));
		}
	}
	@Override
	protected void deliverResponse(XmlPullParser response) {
		mListener.onResponse(response);
	}
}

	private void requestXml() {
		RequestQueue mRequestQueue = Volley.newRequestQueue(this);
		XMLRequest xmlRequest = new XMLRequest("http://flash.weather.com.cn/wmaps/xml/china.xml", new Response.Listener<XmlPullParser>() {
			@Override
			public void onResponse(XmlPullParser response) {
				XmlParser(response);
			}
		}, new Response.ErrorListener() {
			@Override
			public void onErrorResponse(VolleyError error) {
				// TODO Auto-generated method stub
			}
		});
		mRequestQueue.add(xmlRequest);
	}

指定自己Request(GsonRequest 

注:需要匯入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));
			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);
	}
}
private void requestGson() {
	RequestQueue mRequestQueue = Volley.newRequestQueue(this);
	GsonRequest<Weather> gsonRequest = new GsonRequest<Weather>("http://www.weather.com.cn/data/sk/101010100.html", Weather.class, new Response.Listener<Weather>() {
		@Override
		public void onResponse(Weather weather) {
			WeatherInfo weatherInfo = weather.getWeatherinfo();
			Log.d(TAG, "city is " + weatherInfo.getCity());
			Log.d(TAG, "temp is " + weatherInfo.getTemp());
			Log.d(TAG, "time is " + weatherInfo.getTime());

		}
	}, new Response.ErrorListener() {
		@Override
		public void onErrorResponse(VolleyError error) {
			Log.e("TAG", error.getMessage(), error);

		}
	});
	mRequestQueue.add(gsonRequest);
}

框架執行機制


原始碼總結:

1. RequestQueue requestQueue = Volley.newRequestQueue(this);

 ①.stack == null,判斷這個版本9,確定使用HttpURLConnection還是HttpClient

 ②.根據stack建立NetWork物件

 ③.建立RequestQueue,並start<建立一個快取執行緒CacheDispatcher和四個網路執行緒NetworkDispatcher>

 2. requestQueue.add(request);

 ①.判斷是否可以快取,如果可以,加入快取佇列,否則,加入網路請求佇列。request.setShouldCache(false);
 ②.快取執行緒會一直在後臺執行,不斷的取出響應結果,是否為null,是否過期,兩者不成立則Request.parseNetworkResponse()
 ③.網路請求執行緒也是在不斷的執行的,會呼叫Network.performRequest()去傳送請求,將請求結果封裝成NetworkResponse物件返回
 ④.呼叫Request.parseNetworkResponse解析NetworkResponse
 ⑤.呼叫ExecutorDelivery.postResponse()回撥解析出的資料
 ⑥.呼叫Request.deliverResponse()方法
 ⑦.最後我們再在這個方法中將響應的資料回撥到Response.Listener的onResponse()方法

Volley1原始碼下載(StringRequest,JsonRequest,JsonArrayRequest)

Volley2原始碼下載(ImageRequest,ImageLoader,NetWorkImageView)

Volley3原始碼下載(XmlRequest,GsonRequest)

Volley4原始碼下載(執行機制)