android网络框架volley学习之基本数据类

来源:互联网 发布:网络机顶盒有哪些牌子 编辑:程序博客网 时间:2024/06/05 17:09

    volley网络框架中并没有直接采用android中已有的请求类和响应类,而是自己定义了这些类,将请求和响应封装在自定义的类中。为了实现缓存机制,同时定义了缓存体类和缓存头类。

    在介绍Request类之前,先介绍一下请求和响应的结构。请求体是客户端向服务器发出请求的数据的包装,它由请求行、请求头和请求体构成。其中请求行中包含着请求方法(一般是GET和POST)、请求路径和所使用的协议版本。整个请求的结构如下图所示:


请求消息的结构                                        响应消息的结构

    备注:对于GET方法来说,请求体中一般为空,它的请求体一般放在请求路径中。

    而响应同样由三部分构成:响应行(由协议版本、响应码和message组成)、响应头和响应体构成,结构如上图所示。

    具体的请求头和响应头有如下几种:

        


    下面逐个查看这几个基本的数据类:

Request类

public abstract class Request<T> implements Comparable<Request<T>>{//设置参数的编码格式private static final String DEFAULT_PARAMS_ENCODING = "utf-8";//定义方法接口public interface Methods{int DEFAULT_GET_OR_POST = -1;int GET = 0;int POST = 1;int PUT = 2;int DELETE = 3;}//访问的网络地址private final String mUrl;//在请求队列中的位置private Integer mSequeue;//当前请求所在的队列private RequestQueue mRequestQueue;//当前请求是否需要缓存private boolean mShouldCache;//当前请求是否取消private boolean mCanceled = false;//当前请求的请求方法private int mMethod;//标志private Object mTag;//当前请求的 缓存体private Cache.Entry mCacheEntry;//错误传送接口private Response.ErrorLister<T> mErrorListener;//请求构造函数public Request(int method,String url,Response.ErrorLister listener){this.mMethod = method;this.mUrl = url;this.mErrorListener = listener;}//设置请求的方法public void setMethod(int method){this.mMethod = method;}//获取请求的方法public int getMethod(){return mMethod;}//设置标志public void setTag(Object tag){this.mTag = tag;}//获取标志public Object getTag(){return mTag;}//为当前请求设置它所属的请求队列public void setRequestQueue(RequestQueue requestQueue){this.mRequestQueue = requestQueue; }//为当前请求设置在队列中的位置public final void setSequeue(int sequeue){this.mSequeue = sequeue;}//获取当前请求在队列中的位置public int getSequeue(){return mSequeue;}//获取请求的url地址public String getUrl(){return mUrl;}//获取缓存的关键字 这里将url作为缓存的关键字public String getCacheKey(){return getUrl();}//设置缓存体public void setCacheEntry(Cache.Entry entry){this.mCacheEntry = entry;}//获取存在当前请求中的缓存体public Cache.Entry getCacheEntry(){return mCacheEntry;}//取消当前的请求public void cancel(){mCanceled = true;}//判断 当前请求是否取消public boolean isCancel(){return mCanceled;}//设置当前请求是否需要缓存public final void setShouldCache(boolean shoulsCache){mShouldCache = shoulsCache;}//判断当前请求是否需要缓存public boolean shouldCache(){return mShouldCache;}//获取当前请求的请求头。如果网络访问时需要此信息,则重写此方法向Map中添加请求头信息。public Map<String,String> getHeaders(){return Collections.emptyMap();}//获取当前请求的请求参数,请求有参数时需要重写此方法。protected Map<String, String> getParams(){return null;}//对于post请求获取它的请求参数,protected Map<String, String> getPostParams(){return getParams();}//获取post请求参数的编码格式protected String getPostParamsEncoding(){return getParamsEncoding();}//获取请求参数的编码private String getParamsEncoding() {return DEFAULT_PARAMS_ENCODING;}//获取post请求的请求内容类型public String getPostBodyContentType(){return getBodyContentType();}//获取请求的请求内容类型public String getBodyContentType() {return "application/x-www-form-urlencoded; charset="+DEFAULT_PARAMS_ENCODING;}public byte[] getBody(){Map<String, String> params = getParams();if(params != null && params.size()>0){return encodeParameters(params,getParamsEncoding());}return null;}         //根据传递的编码方式将获取到的参数转换成字节数组private byte[] encodeParameters(Map<String, String> params,String paramsEncoding) {StringBuilder encodedParams = new StringBuilder();try {for(Map.Entry<String, String> entry : params.entrySet()){encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding));encodedParams.append('=');encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding));encodedParams.append('&');}return encodedParams.toString().getBytes(paramsEncoding);} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}//需要重写的方法 将NetworkResponse对象转化成 Response对象abstract protected Response<T> parseNetworkResponse(NetworkResponse response);/*需要重写的方法 负责将response对象解析后传回客户端,一般情况下 自定义的request会在其构造函数中引入一个response.Listener参数,再重写此方法时调用mListener.onResponse()方法,让response在其中被解析并传回客户端*/abstract protected void deliverResponse(T response);//发生错误时,移交给错误监听器处理public void deliverError(VolleyError error){if(mErrorListener != null){mErrorListener.onErrorResponse(error);}}public void finish(){if(mRequestQueue != null){mRequestQueue.finish(this);}}//为请求事件添加一个事件输出,用于调试程序public void addMarker(String tag) {if(MarkerLog.ENABLED){mEventLog.add(tag,Thread.currentThread().getId());}else if(mRequestBirthTime == 0){mRequestBirthTime = SystemClock.elapsedRealtime();}}@Overridepublic int compareTo(Request<T> arg0) {// TODO Auto-generated method stubreturn 0;}public int getTimeoutMs() {// TODO Auto-generated method stubreturn 0;}}

NetworkResponse类

此类为response的一个过度类,由标准的HttpResponse响应重新构造而成。由它的构造函数不然看出,这个类中封装了响应的状态码、响应体和响应头以及判断服务器对应的资源是否修改。

    //属性:状态码  数据   响应头       public NetworkResponse(int statusCode, byte[] data, Map<String, String> headers,            boolean notModified) {        this.statusCode = statusCode;        this.data = data;        this.headers = headers;        this.notModified = notModified;    }

Response类

response类相对简单点,它主要封装了由用户通过实现abstract protected Response<T> parseNetworkResponse( response)从networkResponse对象中将数据进行解析,转化成客户端所需要的数据格式(客户端需要图片则将数据通过文件输出流转换成图片,如果需要字符串则生成字符串)。

public static <T> Response<T> success(T result, Cache.Entry cacheEntry) {        return new Response<T>(result, cacheEntry);    }private Response(T result, Cache.Entry cacheEntry) {        this.result = result;        this.cacheEntry = cacheEntry;        this.error = null;    }
Entry类

public class Entry {                //本地缓存的响应体public byte[] data;                //标志public String etag;                //缓存的生存时间public long ttl;                //缓存的soft生存时间(不太懂)public long softTtl;                //服务器做出此响应的时间public long serverDate;                //响应头public Map<String, String> responseHeaders = Collections.emptyMap();                //是否过期public boolean isExpired(){return this.ttl < System.currentTimeMillis();}                //是否需要更新public boolean refreshNeeded(){return this.softTtl < System.currentTimeMillis();}}

CacheHeader类

    此类将entry类的数据换成数据的长度。个人觉得这个类的存在就是为了减少内存的占有,不然在DiskBasedCache类中的map集合中要添加entry类显然是内存的过度的消耗,故volley设计者设计CacheHeader类提供一个类似于索引的功能。

static class CacheHeader {               //缓存的大小        public long size;//缓存头的关键字        public String key;//缓存头的标志        public String etag;        public long serverDate;        public long ttl;        public long softTtl;        public Map<String, String> responseHeaders;        private CacheHeader() { }        //由缓存体转换成缓存头        public CacheHeader(String key, Entry entry) {            this.key = key;            this.size = entry.data.length;            this.etag = entry.etag;            this.serverDate = entry.serverDate;            this.ttl = entry.ttl;            this.softTtl = entry.softTtl;            this.responseHeaders = entry.responseHeaders;        }       //由缓存头构造缓存体       public Entry toCacheEntry(byte[] data) {    Entry e = new Entry();    e.data = data;    e.etag = this.etag;    e.serverDate = this.serverDate;    e.softTtl = this.softTtl;    e.ttl = this.ttl;    e.responseHeaders = this.responseHesders;    return e; }

    以上就是Volley网络框架中的自定义的基本数据类,了解他们的结构有助于再往下深入学习此框架的逻辑处理结构。

   不对请指正,谢谢!

0 0
原创粉丝点击