概述与参考
参考:Volley源码解析
volley为齐射的意思,因此它主要用于操作数据量少但访问频繁的时候。
Volley.java
它就是一个工具类,是整个框架的入口(不使用它也行)。该类中只有四个静态方法(最终都调用了含有三个参数的方法),都返回了RequestQueue对象。源码如下:
newRequestQueue(Context context, HttpStack stack, int maxDiskCacheBytes)
第三个参数规定了磁盘缓存的最大容量(单位为byte),如果该值<=-1,那么就使用默认的值(5M)。主要代码如下: public static RequestQueue newRequestQueue(Context context, HttpStack stack, int maxDiskCacheBytes) {
……
if (stack == null) {
if (Build.VERSION.SDK_INT >= 9) {
stack = new HurlStack();
} else {
// Prior to Gingerbread, HttpUrlConnection was unreliable.
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
}
Network network = new BasicNetwork(stack);
RequestQueue queue;
if (maxDiskCacheBytes <= -1)
{
// No maximum size specified
queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
}
else
{
// Disk cache size specified
queue = new RequestQueue(new DiskBasedCache(cacheDir, maxDiskCacheBytes), network);
}
queue.start();
return queue;
}
从该方法中也可以看出:Volley.java的主要目的就是创建RequestQueue实例,并调用该实例的start()。因此,我们完全可以不使用该类,自己创建RequestQueue。
stack
其中HurlStack()和HttpClientStack()都实现了HttpStack接口。前者是基于HttpURLConnection,而后者基于HttpClient。
在2.3(版本9)之前,HttpURLConnection有bug,建议使用AndroidHttpClient(对HttpClient进一步封装),所以这里使用了基于HttpClient的HttpClientStack;而2.3之后,HttpURLConnection性能更好,所以使用基于HttpURLConnection的HttpStack。
userAgent
在省略的部分还创建了String类型的userAgent,它主要用于设置http头文件的User-Agent属性。而HttpURLConnection默认就会添加该属性,所以不需要进行设置。
HttpStack.java
用于处理http请求,并返回请求结果。目前只有HurlStack和HttpClientStack两个实现类。它只有一个方法,如下:
public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
throws IOException, AuthFailureError;
第二个参数表示在发起请求前添加的额外的headers。
Request.java
网络请求的基类。它里面封装了一次网络请求的基本信息以及对返回结果的处理,如:网络请求的url(变量mUrl),网络重定向的url(变量mRedirectUrl),网络请求方式(变量mMethod)——post请求,get请求等,本次网络请求的标识(变量mTag),请求优先级(变量mSequence),是否要进行缓存(变量mShouldCache,默认时该值为true)等。类似于使用Handler时的Message。
它是一个抽象类,子类必须重写
abstract protected void deliverResponse(T response);
abstract protected Response<T> parseNetworkResponse(NetworkResponse response);
第二个方法用于解析从网络获取的原数据,第一个方法将解析后的内容传递给相应的回调(它的参数是第二个方法的返回值)。
在使用Post方式进行http请求时,可能需要重写下面两个该当中的一个
public byte[] getBody() throws AuthFailureError{}
protected Map<String, String> getParams() throws AuthFailureError {}
这两个方法主要用来生成http请求报文中的请求数据部分。参考http请求报文和响应报文。
在getBody()方法中,会将getParams()返回的数据进行重组,生成post请求时的请求数据。因此,如果需要生成post请求时的请求数据,只需要重写getParams(),将请求数据中的key与value存储到map中,并将map返回。如,post需要提交的数据为name="a",psw=“b"。那么getParams()如下:
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("name", "a");
params.put("psw", "b");
return params;
}
RequestQueue.java
网络请求队列。它里面存储着不同的Request。类似于使用Handler时的MessageQueue。
通过调用add(Request)可将不同的Request添加到RequestQueue中,而queue内部会不断调用它所存储的request进行网络访问,并将访问结果返回到主线程中。
RequestFilter
RequestQueue的内部接口,用于过滤是否取消某个request。该接口中只有一个方法
boolean apply(Request<?> request)
如果该方法返回true,那么在RequestQueue取消操作中就会取消该request,否则不会取消。使用到该类的主要有两个方法
public void cancelAll(RequestFilter filter) {
synchronized (mCurrentRequests) {
for (Request<?> request : mCurrentRequests) {
if (filter.apply(request)) {
request.cancel();
}
}
}
}
public void cancelAll(final Object tag) {
if (tag == null) {
throw new IllegalArgumentException("Cannot cancelAll with a null tag");
}
cancelAll(new RequestFilter() {
@Override
public boolean apply(Request<?> request) {
return request.getTag() == tag;
}
});
}
从第二个方法可以看出tag的用途:用于对Request进行唯一的标识。