[Android]Volley源码分析(二)

上一篇介绍了Volley的使用,主要接触了Request与RequestQueue这两个类,这篇就来了解一下这两个类的具体实现。

Request类图:

Request类: Request是一个抽象类,其中的主要属性:

mMethod: 请求方法,目前支持GET, POST, PUT, DELETE, HEAD, OPTIONS,TRACE, PATCH方法

mUrl: 请求Url

mErrorListener: 错误处理监听器,请求出错时调用

mSequence: 请求的序号,相同优先级的请求在请求队列中根据序号来进行排序,序号低的排在队列前面。

mRequestQueue: 该请求所在的请求队列

mCacheEntry: When a request can be retrieved from cache but must be refreshed from the network, the cache entry will be stored here so that in the event of a "Not Modified" response, we can be sure it hasn‘t been evicted from cache.

mRetryPolicy: 请求的重试策略

mShouldCache: 该请求的响应是否被缓存

mCanceled: 该请求是否能被取消

mResponseDelivered: 请求的响应是否已经交付。

另外还有一个mTag属性,用来标记Request,可以在RequestQueue中根据tag来批量取消Request。

主要方法包括:

getBody(): 返回请求体的字节数组表示。默认实现为返回null,所以如果是POST或PUT请求,子类需要重写这个方法。

parseNetworkResponse() 与deliverResponse()为抽象方法,由子类实现。parseNetworkResponse用来解析原始的响应信息,并返回一个特定的响应类型即Response<T>中的T类型结果。deliverResponse用来将解析好的响应结果交付给监听器进行处理。

默认情况下,Request的Priority都是Normal,如下源码:

 1 /**
 2      * Priority values.  Requests will be processed from higher priorities to
 3      * lower priorities, in FIFO order.
 4      */
 5     public enum Priority {
 6         LOW,
 7         NORMAL,
 8         HIGH,
 9         IMMEDIATE
10     }
11
12     /**
13      * Returns the {@link Priority} of this request; {@link Priority#NORMAL} by default.
14      */
15     public Priority getPriority() {
16         return Priority.NORMAL;
17     }

Request实现Comparable接口来对Request的优先级进行比较,从而决定Request在队列中的顺序。优先级越高,在请求队列中排得越前,相同优先级的序号越低,排得越前。

 1 /**
 2      * Our comparator sorts from high to low priority, and secondarily by
 3      * sequence number to provide FIFO ordering.
 4      */
 5     @Override
 6     public int compareTo(Request<T> other) {
 7         Priority left = this.getPriority();
 8         Priority right = other.getPriority();
 9
10         // High-priority requests are "lesser" so they are sorted to the front.
11         // Equal priorities are sorted by sequence number to provide FIFO ordering.
12         return left == right ?
13                 this.mSequence - other.mSequence :
14                 right.ordinal() - left.ordinal();
15     }

Request派生出三个子类JsonRequest、ImageRequest、ClearCacheRequest。其中

1. JsonRequest<T>也是一个抽象类,可以发送一个Json表示的请求体,并返回一个T类型的响应,主要包括

mListener: 请求成功的监听器

mRequestBody:请求体的Json字符串表示。

parseNetworkResponse()仍为抽象方法,getBody()返回mRequestBody的字节数组。deliverResponse中调用mListener的onResponse方法,该方法由用户自己定义。参考上篇。

1  @Override
2     protected void deliverResponse(T response) {
3         mListener.onResponse(response);
4     }

JsonArrayRequest、JsonObjectRequest继承自JsonRequest,分别表示返回一个JsonArray响应的请求与返回一个JsonObject响应的请求。JsonArrayRequest的parseNetworkResponse实现,JsonObjectRequest与之类似,不同的是返回JSONObject类型的响应,而不是JSONArray

 1 @Override
 2     protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
 3         try {
 4             String jsonString =
 5                 new String(response.data, HttpHeaderParser.parseCharset(response.headers));
 6             return Response.success(new JSONArray(jsonString),
 7                     HttpHeaderParser.parseCacheHeaders(response));
 8         } catch (UnsupportedEncodingException e) {
 9             return Response.error(new ParseError(e));
10         } catch (JSONException je) {
11             return Response.error(new ParseError(je));
12         }
13     }

2. ImageRequest 用来根据一个URL来请求一个位图Bitmap,包括属性

mListene:用来接收经过解码的位图的监听器

mMaxWidth: 解码位图的最大宽度,

mMaxHeight:解码位图的最大高度

如果mMaxWidth,mMaxHeight都为0,则保持位图的原始尺寸,如果其中一个不为0,则按照原始位图的宽高比进行解码,如果都不为0, 则将解码成最适合width x height区域并且保持原始位图宽高比的位图。

ImageRequest的优先级是最低的。

1 @Override
2     public Priority getPriority() {
3         return Priority.LOW;
4     }

3. ClearCacheRequest 一个模拟的用来清理缓存的请求

mCache:需要清理的缓存

mCallback:缓存清理完后在主线程中被调用的回调接口。

parseNetworkResponse与deliverResponse都是空实现,因为这是一个模拟的Request,没有实际的网络请求。

ClearCacheRequest的优先级是最高的。

1 @Override
2     public Priority getPriority() {
3         return Priority.IMMEDIATE;
4     }

不早了,今天先到这。明天继续。

[Android]Volley源码分析(二)

时间: 2024-10-16 04:55:45

[Android]Volley源码分析(二)的相关文章

[Android]Volley源码分析(二)Cache

Cache作为Volley最为核心的一部分,Volley花了重彩来实现它.本章我们顺着Volley的源码思路往下,来看下Volley对Cache的处理逻辑. 我们回想一下昨天的简单代码,我们的入口是从构造一个Request队列开始的,而我们并不直接调用new来构造,而是将控制权反转给Volley这个静态工厂来构造. com.android.volley.toolbox.Volley: public static RequestQueue newRequestQueue(Context conte

[Android]Volley源码分析(四)

上篇中有提到NetworkDispatcher是通过mNetwork(Network类型)来进行网络访问的,现在来看一下关于Network是如何进行网络访问的. Network部分的类图: Network有一个实现类BasicNetwork,它有一个mHttpStack的属性,实际的网络请求是由这个mHttpStack来进行的,看BasicNetwork的performRequest()方法, 1 @Override 2 public NetworkResponse performRequest

[Android]Volley源码分析(叁)Network

如果各位看官仔细看过我之前的文章,实际上Network这块的只是点小功能的补充.我们来看下NetworkDispatcher的核心处理逻辑: <span style="font-size:18px;">while (true) { try { // Take a request from the queue. request = mQueue.take(); } catch (InterruptedException e) { // We may have been int

[Android]Volley源码分析(肆)应用

通过前面的讲述,相信你已经对Volley的原理有了一定了解.本章将举一些我们能在应用中直接用到的例子,第一个例子是 NetworkImageView类,其实NetworkImageView顾名思义就是将异步的操作封装在了控件本身,这种设计可以充分保留控件的移植性和维护性.NetworkImageView通过调用setImageUrl来指定具体的url: public void setImageUrl(String url, ImageLoader imageLoader) { mUrl = ur

[Android] Volley源码分析(一)体系结构

Volley:google出的一个用于异步处理的框架.由于本身的易用性和良好的api,使得它能得以广泛的应用.我还是一如既往从源码的方向上来把控它.我们先通过一段简单的代码来了解Volley RequestQueue queue = Volley.newRequestQueue(this); ImageRequest imagerequest = new ImageRequest(url, new Response.Listener<Bitmap>(){ @Override public vo

[Android]Fragment源码分析(二) 状态

我们上一讲,抛出来一个问题,就是当Activity的onCreateView的时候,是如何构造Fragment中的View参数.要回答这个问题我们先要了解Fragment的状态,这是Fragment管理中非常重要的一环.我们先来看一下FragmentActivity提供的一些核心回调: @Override protected void onCreate(Bundle savedInstanceState) { mFragments.attachActivity(this, mContainer,

[Android]Volley源码分析(五)

前面几篇通过源码分析了Volley是怎样进行请求调度及请求是如何被实际执行的,这篇最后来看下请求结果是如何交付给请求者的(一般是Android的UI主线程). 类图: 请求结果的交付是通过ResponseDelivery接口完成的,它有一个实现类ExecutorDelivery, 主要有postResponse()与postError()两个方法,分别在请求成功或失败时将结果提交给请求发起者. 1. 首先,在NetworkDispatcher的run()方法中,当服务器返回响应并解析完后,会调用

[Android]Volley源码分析(一)

一. 如何使用Volley? 1. 首先定义一个RequestManager类,用来在Android程序启动时对Volley进行初始化.RequestManager为单例类,因为只有在程序启动时调用,所以不需要考虑并发问题. 1 /** 2 * Manager for the queue 3 */ 4 public class RequestManager { 5 6 /** 7 * 请求队列 8 */ 9 private static RequestQueue mRequestQueue; 1

[Android] Volley源码分析(五)答疑

Volley源码分析系列出了有一段日子了,有不少看官私底下给我留言,同时抛出了一些问题.对于一些比较简单的问题我们跳过去,这两天接到网友是@smali提出的问题.不得不赞一下这位看官看源码时候的细腻程度,我引出这个问题供大家一块思考一下. Q:在写入文件头数据的时候为何不直接写入Int而是通过移位的方式来完成? 我们来看一下对应的源码: writeInt(os, CACHE_MAGIC); static void writeInt(OutputStream os, int n) throws I