Volley详解(二)——请求(Request)

来源:互联网 发布:mac不需要杀毒软件 编辑:程序博客网 时间:2024/05/19 05:39

概述

本篇介绍请求相关的类,主要包括Request<T>RequestQueue两部分。


Part 1 ——Request

成员变量

Request<T>的主要属性如下:

  • int mMethod:请求的类型,即GET、POST、PUT等
  • String mUrl:请求的url
  • String mIdentifier:请求的唯一标识
  • Response.ErrorListener mErrorListener:用于错误处理的回调接口,是Response的静态内部类
  • Integer mSequence:记录请求到达的先后顺序
  • RequestQueue mRequestQueue:所在在请求队列
  • boolean mShouldCache:请求结果是否需要缓存
  • boolean mCanceled:请求是否被取消了
  • boolean mResponseDelivered:请求结果是否已处理
  • Cache.Entry mCacheEntry:缓存,用于检验缓存一致性

多数属性都比较容易理解,其他的只是列出,会在后续博客逐步涉及。

构造函数

Request类有两个重载的构造函数,而且很简单:

public Request(String url, Response.ErrorListener listener);public Request(int method, String url, Response.ErrorListener listener);

必须提供的是url和ErrorListener,method如果没有,默认值是GET。另外,只有错误处理接口ErrorListener是放在Request类中的,而正常情况下的响应处理接口是放在子类中的,这体现了框架的扩展性。

抽象方法

有两个子类必须重写的抽象方法:

abstract protected Response<T>parseNetworkResponse(NetworkResponse response);

将原始的网络请求的返回结果转化为客户端需要的类型<T>,该方法会在工作线程中被调用,如果该方法返回null,则后续的deliverResponse()将不会执行。

abstract protected void deliverResponse(T response);

将返回的结果交给相应的Listener处理,如果前一阶段parseNetworkResponse()失败,则该方法不会被调用。

其他重要方法

另外还有两个重要方法,与请求参数有关,子类如果要用到请求参数,则需要重写这两个方法。

protected Map<String, String> getParams();

该方法返回由请求参数key-value pair组成的MapRequest类中并没有表示参数的属性,因此,子类如果使用请求参数,直接重写该方法,令其返回一个存储了参数的Map即可。

public byte[] getBody();

返回byte[]格式的请求请求参数,默认情况下会调用getParams(),然后将请求的键值对以key=value&key=value的形式连接起来。

Request的子类

Request<T>是个抽象类,必须继承后才能使用,Volley已经给出了三种实现:StringRequestJsonRequestImageRequest,而JsonRequest也是抽象类,它有JsonObjectRequestJsonArrayRequest两个子类。

StringRequest

  • 属性
    在基类的基础上,增加了响应回调接口Response.Listener mListener

  • 方法
    只重写了两个抽象方法
    parseNetworkResponse(),将网络请求原始结果的body部分转化为String并返回。
    deliverResponse(),调用mListener.onResponse(response)处理结果。

JsonRequest

基本原理与StringRequest相同,不同的是增加了对请求参数的支持。
Volley中并没有RequestParams这样表示参数的类,所以在JsonRequest中,请求体是用StringJsonObject表示的。

  • 如果用String,则是key=value&key=value的形式;
  • 如果用JsonObject,则请求体的键值对即为JsonObject的键值对。

以上两种形式的请求体在两个子类JsonObjectRequestJsonArrayRequest的构造函数中都可以使用。

ImageRequest

与前面两个子类相比,大体思路相同,但增加了很多调整图片尺寸的代码。构造函数如下:

public ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight, ScaleType scaleType, Config decodeConfig, Response.ErrorListener errorListener);

可以通过maxWidthmaxHeight以及scaleType参数控制返回的Bitmap的大小。

注意到一个细节,对于Bitmap类,在parseNetworkResponse()函数中需要调用BitmapFactory.decodeByteArray()获取Bitmap,改方法很消耗内存,所以设计者给该方法进行了加锁处理,保证同时只进行一个parseNetworkResponse()操作。


Part 2 ——RequestQueue

存储各种状态下的Request,并负责启动工作线程,是Volley的枢纽。

Request的集合

维护了4个集合,用于表示各种状态下的Request:

  • PriorityBlockingQueue<Request<?>> mCacheQueue
    缓存请求队列

  • PriorityBlockingQueue<Request<?>> mNetworkQueue
    网络请求队列

  • Set<Request<?>> mCurrentRequests
    正在执行中的网络请求,文档中用了“in flight”这个词,很贴切

  • Map<String, Queue<Request<?>>> mWaitingRequests
    等待请求的集合,如果一个请求正在被处理(即in flight)并且可以被缓存,则后续的具有相同url的请求,将进入此等待队列,该Map的键是RequestcacheKey,默认为mMethod + mUrl

工作类

维护了其他几个核心类的引用,调度框架的整体工作:

  • Cache mCache:缓存类
  • Network mNetwork:网络请求类
  • NetworkDispatcher[] mDispatchers:网络分发线程
  • CacheDispatcher mCacheDispatcher:缓存分发线程
  • ResponseDelivery mDelivery:处理请求结果的接口

add()方法

public <T> Request<T> add(Request<T> request);

将一个Request添加到RequestQueue,具体工作如下:

  1. Request添加到mCurrentRequest中,防止同一个请求被重复执行。
  2. 判断该请求是否需要缓存,如果不需要,直接将其加入mNetworkQueuereturn,等待网络分发线程处理。
  3. mWaitingRequests中查找该RequestcacheKey,如果找到,转4,否则,转5。
  4. 说明有相同的请求已经被发出,不需要重新发起网络请求。只需加入mWaitingRequests即可,即将Request加入到cacheKey对应的Queue中。
  5. 说明该请求没有在执行中,需要发起网络请求。一方面,将Request加入到mCacheQueue,等待缓存分发线程处理;另一方面,在mWaitingRequests添加键值对<chcheKey, null>,表示改请求已在处理中,后续到达的具有相同cacheKey的请求不必重复发起。

其他方法

  • start()
    用于启动RequestQueue,该方法会初始化CacheDispatcher和所有的NetworkDispatcher并启动它们,工作线程会从相应的队列中循环不断地取出Request并执行。Volley.newRequestQueue()方法中会调用start(),所以此时就不需要我们手动调用start()了。
  • stop()
    该方法会使所有的工作线程退出。
  • finish(Request<T> request)
    表示该请求已处理完毕,从mRequestQueue中移除。
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 四个月婴儿漏屎怎么办 母乳喂养6个月才11斤怎么办 过期的果泥肉泥怎么办? 孩子被开水烫了怎么办 小儿喝开水烫了怎么办 小孩不识字怎么办17-18 3岁宝宝不识数字怎么办 小孩数字写反了怎么办 3岁宝宝乱啃东西怎么办 闹钟的指针松了怎么办 手机想让它横屏怎么办 教孩子写作业头都被气炸了怎么办 2岁宝宝大小脸怎么办 宝宝2岁半不认识颜色怎么办 宝宝11个多月突然排斥妈妈怎么办 5个月婴儿粘妈妈怎么办 3岁宝宝记不住颜色怎么办 3岁宝宝不认字怎么办 墙纸被宝宝弄上各种颜色怎么办 三周半的孩子不认识数字怎么办 3岁幼儿不会数数怎么办 四岁宝宝不认识数字怎么办 三岁宝宝不认识数字怎么办 4岁半了不认识数字怎么办 5岁小朋友数字不认识怎么办 孩子读一年级字都不识几个怎么办 宝宝二周多了不分颜色怎么办 4岁儿童手指脱皮怎么办 孩子老是不会写2怎么办 宝宝胃浅容易吐怎么办 农村户口小孩去城里读书怎么办 小孩从城市回农村读书怎么办 天冷了怎么办教案反思 小孩上幼儿园不爱学习怎么办 曰光灯管监控要反光怎么办 立邦乳胶漆墙面脏了怎么办 橱柜门黑色边颜色花了怎么办 地板上有真实漆怎么办 吸了泡泡球的气怎么办 办公室上班坐着太累怎么办 金雀盆景生虫怎么办