初次接触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,还是那句,刚刚起步,期待提高。









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