初次接觸volley網絡框架,進行初步封裝使用

volley是google官方出的一個Android網絡訪問庫,可以進行http訪問和圖片的網絡異步獲取(類似於imageloader)。

由於纔剛開始練習面向對象編程,所以就想對volley進行初步封裝根據自己的喜好來使用。

先說說volley的最基本用法:

在導入了jar後,在需要做網絡訪問的地方申請一個請求隊列:

	private RequestQueue mRequestQueue;
        mRequestQueue = Volley.newRequestQueue(this);
一般在一個activity中只要一個請求隊列,在需要訪問網絡時就new一個request實例再add到隊列中就可以了。

建立一個StringRquest(是Request<T>的一個之類):

 StringRequest myRequest = new StringRequest(Method.GET,url, new Listener<String>() {

			@Override
			public void onResponse(String arg0) {
				// TODO Auto-generated method stub
				Log.d("string request success linstener", arg0 + "");
			}
		}, new ErrorListener() {

			@Override
			public void onErrorResponse(VolleyError arg0) {
				// TODO Auto-generated method stub
				Log.d("string request error linstener", arg0.getMessage() + "");
			}
		});
這個是一個最簡單的get方法請求。

還可以建立一個post方法請求:

        StringRequest myRequest = new StringRequest(Method.POST,url, new Listener<String>() {

			@Override
			public void onResponse(String arg0) {
				// TODO Auto-generated method stub
				Log.d("string request success linstener", arg0 + "");
			}
		}, new ErrorListener() {

			@Override
			public void onErrorResponse(VolleyError arg0) {
				// TODO Auto-generated method stub
				Log.d("string request error linstener", arg0.getMessage() + "");
			}
		}){

			@Override
			protected Map<String, String> getParams() throws AuthFailureError {
				// TODO Auto-generated method stub
				Map<String, String> map = new HashMap<String, String>();
				return map;
			}
        	
        };
在post方法中,需要設置post所帶的參數,就重載request的getParams方法,以map的形式輸入。

最後就是把建立好的request實例add到隊列中:

        mRequestQueue.add(myRequest);
這樣volley的基本使用就完成了。


到這裏,就覺得要根據不同的請求每次new一個不同request,而且有時候還要重載各種方法,所以就打算做一個簡單初步的封裝使用。


最開始我先建立兩個基類:

1,AbsRequest.java 這個類是Request的抽象(下面這個抽象的實現會詳細說明):

public abstract class AbsRequest<T> extends Request<T> {
	//父類函數
	public AbsRequest(int method, String url, ErrorListener listener) {
		super(method, url, listener);
	}
	//訪問網絡成功後返回的Response處理
	@Override
    protected abstract Response<T> parseNetworkResponse(NetworkResponse response) ;
	//編輯頭部需要帶的信息
	@Override
	public abstract Map<String, String> getHeaders() throws AuthFailureError ;
	//獲取訪問網絡的方式get/post
	@Override
	public abstract int getMethod() ;

	
	//獲取需要訪問的地址
	@Override
	public abstract String getUrl() ;

	//獲取訪問網絡需要帶的參數
	@Override
	protected abstract Map<String, String> getParams() throws AuthFailureError ;
	

	//訪問網絡成功返回後的操作
	@Override
	protected abstract void deliverResponse(T paramT);
	
	
}

2.RequestCallBack.java 這個是網絡訪問後對應的回調:

public abstract class RequestCallBack implements Response.Listener<String>,Response.ErrorListener{
	
	public Response.Listener<String> mSuccessCallBack = new Listener<String>() {

		@Override
		public void onResponse(String arg0) {
			// TODO Auto-generated method stub
			RequestCallBack.this.onResponse(arg0);
		}
	};
	
	public Response.ErrorListener mErrorCallBack = new ErrorListener() {

		@Override
		public void onErrorResponse(VolleyError arg0) {
			// TODO Auto-generated method stub
			RequestCallBack.this.onErrorResponse(arg0);
		}
	};
	
	@Override
	public abstract void onResponse(String arg0);

	@Override
	public abstract void onErrorResponse(VolleyError arg0);
	
}
然後,現在每一個網絡請求都建立一個類,繼承AbsRequest,我這裏就建立一個TextRequest,訪問百度翻譯api的(在註釋中有詳細的講解):

public class TextRequest extends AbsRequest<String> {
		public RequestCallBack mCallBack; 
		public Map<String, String> mPostMap;
		public Map<String, String> mHeadersMap;
		private int method;
		private static String url = "http://192.168.1.36:8080/volloryText/post.php";
		//private static String url = "http://192.168.1.36:8080/volloryText/post.php";
		private static String urls = "http://openapi.baidu.com/public/2.0/bmt/translate";
		private static String BAIDUKEY = "xxxxxxxxxxxxx";
		private static String src = "我不認識你的啊";
		private static String parm; 
		//用於初始化的,可以根據自己的實際需要添加參數
		/*覺得值得一提的就是,super中設置的super(0,url, callBack.mErrorCallBack);
		 * 第一個參數是網絡訪問方式get/post,第二個參數是地址的url
		 * 我曾經出現過的疑問就是如果我get方法需要再url中帶參數,我是不是要在初始化實體的時候就把帶參數的url建立好
		 * 如果是的話,那建立這個獨立的類的意義就不大了,所以答案是否定的。
		 * 這裏super只是設定一個默認值,到真正訪問網絡的時候,會優先使用重載函數getUrl()和getMethod()等的返回值。
		 * 所以我們只需要把值傳入內部進行處理,在外只要一句話就能初始化實體。
		 * 
		 */
		public TextRequest(int method,RequestCallBack callBack) {
			super(0,url, callBack.mErrorCallBack);
			// TODO Auto-generated constructor stub
			this.method = method;
			this.mCallBack = callBack;
			this.setShouldCache(false);
		}
	
	
		public TextRequest(int method,String id,String name,String sex,RequestCallBack callBack) {
	//		super(url + "?" + parm, callBack.mSuccessCallBack, callBack.mErrorCallBack);
			super(0,url, callBack.mErrorCallBack);
		
			this.setShouldCache(false);
		}
		
	
		/*
		 * (non-Javadoc)
		 * @see com.example.textvolley.AbsRequest#parseNetworkResponse(com.android.volley.NetworkResponse)
		 * 這個類是處理返回的信息類型的,response中包含就所有訪問網絡後返回的數據,這裏是用volley中的一個工具類HttpHeaderParser來定義返回數據的編碼方式
		 * 因爲volley在默認情況加是不支持中文的,所以如果在訪問的http頭信息中沒有定義編碼方式,他就會默認使用iso-8859-1
		 * 我們就需要HttpHeaderParser.parseCharset(response.headers, "UTF-8")來指定,不然有可能會出現中文亂碼
		 */
		
		@Override
	    protected Response<String> parseNetworkResponse(NetworkResponse response) {
			String parsed;
		    try {
		      parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers, "UTF-8"));
		    } catch (UnsupportedEncodingException e) {
		      parsed = new String(response.data);
		    }
		    return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
	    } 
	
		/*
		 * (non-Javadoc)
		 * @see com.example.textvolley.AbsRequest#getHeaders()
		 * 設置頭信息
		 */
		@Override
		public Map<String, String> getHeaders() throws AuthFailureError {
			// TODO Auto-generated method stub
			if (mHeadersMap != null){
			mHeadersMap.put("charset", "UTF-8");
			return mHeadersMap;
			}
			else{
				mHeadersMap = new HashMap<String, String>();
				mHeadersMap.put("charset", "UTF-8");
				return mHeadersMap;
			}
		}
		/*
		 * (non-Javadoc)
		 * @see com.example.textvolley.AbsRequest#getMethod()
		 * 設置訪問網絡的方式get/post
		 */
		@Override
		public int getMethod() {
			// TODO Auto-generated method stub
			return this.method;
		}
	
		
		/*
		 * (non-Javadoc)
		 * @see com.example.textvolley.AbsRequest#getUrl()
		 * 設置網絡地址,在這裏可以添加get參數
		 */
		@Override
		public String getUrl() {
			// TODO Auto-generated method stub
			return urls + buildURL();
		}

		/*
		 * (non-Javadoc)
		 * @see com.example.textvolley.AbsRequest#getParams()
		 * 添加post的參數
		 */
		@Override
		protected Map<String, String> getParams() throws AuthFailureError {
			// TODO Auto-generated method stub
			if (mPostMap != null){
				return mPostMap;
			}
			else{
				mPostMap = new HashMap<String, String>();
				mPostMap.put("parm", "我不知道你說什麼");
				return mPostMap;
			}
		}
		/*
		 * 生成get參數的url穿,指定使用utf-8
		 */
		public String buildURL(){
			List<BasicNameValuePair> params = new LinkedList<BasicNameValuePair>();  
			params.add(new BasicNameValuePair("client_id", BAIDUKEY));  
			params.add(new BasicNameValuePair("q", src));  
			params.add(new BasicNameValuePair("from", "auto"));  
			params.add
			(new BasicNameValuePair("to", "wyw"));  
			//對參數編碼  
			String p = URLEncodedUtils.format(params, "UTF-8");  
			
			parm = "?" + p;
			return parm;
		}

		/*
		 * (non-Javadoc)
		 * @see com.example.textvolley.AbsRequest#deliverResponse(java.lang.Object)
		 * 訪問網絡成功後,返回需要做的,一般是調用callback回調。
		 */
		@Override
		protected void deliverResponse(String paramT) {
			// TODO Auto-generated method stub
			System.out.println(paramT);
			mCallBack.mSuccessCallBack.onResponse(paramT);
		}


	
		
	
}

這樣在需要使用翻譯api的地方

 RequestCallBack callBack = new RequestCallBack() {
			
			@Override
			public void onResponse(String arg0) {
				// TODO Auto-generated method stub
				Log.d("string request success linstener", arg0 + "");
			}
			
			@Override
			public void onErrorResponse(VolleyError arg0) {
				// TODO Auto-generated method stub
				Log.d("string request error linstener", arg0.getMessage() + "");
			}
		};
        
		TextRequest baiduRequest = new TextRequest(Method.GET, callBack);
		
		mRequestQueue.add(baiduRequest);

感覺這個activity的代碼可讀性會提高不少。



後記:

1,因爲纔開始嘗試自己寫,沒什麼經驗,所以還是覺得寫得不是很好,特別是callBack的抽象類。希望有更好 的建議

  2,在官方的Request之類中也有很多不同類型的子類,例如jsonOBJ之類的,因爲Request<T>是泛型,我們在 建立AbsRequest的子類時,也可以利用這一點,建立獨特返回類型的子類。只要在重載 parseNetworkResponse時做不同的處理就可以了。

  3,還是那句,剛剛起步,期待提高。









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章