您的位置:首页 > 理论基础 > 计算机网络

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

2015-03-31 20:05 441 查看
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 block
e.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();
}
}
@Override
public int compareTo(Request<T> arg0) {
// TODO Auto-generated method stub
return 0;
}
public int getTimeoutMs() {
// TODO Auto-generated method stub
return 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网络框架中的自定义的基本数据类,了解他们的结构有助于再往下深入学习此框架的逻辑处理结构。

不对请指正,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: