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网络框架中的自定义的基本数据类,了解他们的结构有助于再往下深入学习此框架的逻辑处理结构。
不对请指正,谢谢!
- android网络框架volley学习之基本数据类
- android网络框架volley学习之Volley类
- android学习之volley框架(网络)
- android网络框架volley学习之RequestQueue类
- Android Volley网络框架的基本使用
- Android 网络访问框架 Volley 基本使用
- android网络框架volley学习之整体篇
- android网络框架volley学习之HttpStack接口
- Android框架之网络开发框架Volley
- android框架学习之Volley
- android学习笔记之通过Volley框架实现数据请求
- android常见框架基本使用之-Volley
- Android 网络通信框架Volley学习
- Android网络请求框架Volley学习
- Android 网络请求框架Volley学习笔记
- android Volley网络通信框架学习
- android之官方网络通信框架volley
- Android开发之Volley网络通信框架
- java 服务器 获取web端IP
- Git使用方法
- logback使用
- poj 2482 Cows
- Activity中Flag的解释FLAG_ACTIVITY_SINGLE_TOP
- android网络框架volley学习之基本数据类
- 关于使用Axure RP进行原型开发的一些心得体会
- 一切都是对象(上)
- C++友元函数
- QQ通信原理及QQ是怎么穿透内网进行通信的?
- MYSQL5.1升级到5.5及utf8mb4使用方法
- HDU 1698 Just a Hook(线段树区间更新)
- 十种排序方法总结
- POJ 1930 Dead Fraction (小数化分数)