我们知道,。网络Http沟通,会有一个Request,相同,也将有Response。我们Volley在使用RequestQueue来之前加入的请求。我们将创建一个Request对象,例StringRequest。JsonObjectRequest和ImageRequest等。例如以下各自是前面Demo中的JsonRequest和ImageRequest:

JsonObjectRequest:

    public JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener,
ErrorListener errorListener) {

ImageRequest:

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

Volley中提供了一个基础的Request抽象类,例如以下:

public abstract class Request<T> implements Comparable<Request<T>> {

在这个类中,定义了一些请求中主要的參数变量,如

Method:

    /**
* Request method of this request. Currently supports GET, POST, PUT, DELETE, HEAD, OPTIONS,
* TRACE, and PATCH.
*/
private final int mMethod;

它的值例如以下:

    /**
* Supported request methods.
*/
public interface Method {
int DEPRECATED_GET_OR_POST = -1;
int GET = 0;
int POST = 1;
int PUT = 2;
int DELETE = 3;
int HEAD = 4;
int OPTIONS = 5;
int TRACE = 6;
int PATCH = 7;
}

请求中的Url:

    /** URL of this request. */
private final String mUrl;

一个ErroListener,

    /** Listener interface for errors. */
private final Response.ErrorListener mErrorListener;

还有其他的一些參数,如shouldCache(是否须要缓存)。tag(分类标签)等,而在Request中还提供了以下两个抽象方法。必须由子类实现:

    /**
* Subclasses must implement this to parse the raw network response
* and return an appropriate response type. This method will be
* called from a worker thread. The response will not be delivered
* if you return null.
* @param response Response from the network
* @return The parsed response, or null in the case of an error
*/
abstract protected Response<T> parseNetworkResponse(NetworkResponse response);
    /**
* Subclasses must implement this to perform delivery of the parsed
* response to their listeners. The given response is guaranteed to
* be non-null; responses that fail to parse are not delivered.
* @param response The parsed response returned by
* {@link #parseNetworkResponse(NetworkResponse)}
*/
abstract protected void deliverResponse(T response);

每个子类都必须实现两个方法,

1)parseNetworkResponse

当从网络中获取到Response的时候,怎么去解析相应的请求,这是由各个相应的Request去分析的,比方JsonObjectRequest中:

    @Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString =
new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}

再比方ImageRequest中的:

    @Override
protected Response<Bitmap> parseNetworkResponse(NetworkResponse response) {
// Serialize all decode on a global lock to reduce concurrent heap usage.
synchronized (sDecodeLock) {
try {
return doParse(response);
} catch (OutOfMemoryError e) {
VolleyLog.e("Caught OOM for %d byte image, url=%s", response.data.length, getUrl());
return Response.error(new ParseError(e));
}
}
}

而在doParse中,事实上是对图片进行处理,例如以下:

    private Response<Bitmap> doParse(NetworkResponse response) {
byte[] data = response.data;
BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
Bitmap bitmap = null;
if (mMaxWidth == 0 && mMaxHeight == 0) {
decodeOptions.inPreferredConfig = mDecodeConfig;
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);
} else {
// If we have to resize this image, first get the natural bounds.
decodeOptions.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);
int actualWidth = decodeOptions.outWidth;
int actualHeight = decodeOptions.outHeight; // Then compute the dimensions we would ideally like to decode to.
int desiredWidth = getResizedDimension(mMaxWidth, mMaxHeight,
actualWidth, actualHeight);
int desiredHeight = getResizedDimension(mMaxHeight, mMaxWidth,
actualHeight, actualWidth); // Decode to the nearest power of two scaling factor.
decodeOptions.inJustDecodeBounds = false;
// TODO(ficus): Do we need this or is it okay since API 8 doesn't support it? // decodeOptions.inPreferQualityOverSpeed = PREFER_QUALITY_OVER_SPEED;
decodeOptions.inSampleSize =
findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight);
Bitmap tempBitmap =
BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions); // If necessary, scale down to the maximal acceptable size.
if (tempBitmap != null && (tempBitmap.getWidth() > desiredWidth ||
tempBitmap.getHeight() > desiredHeight)) {
bitmap = Bitmap.createScaledBitmap(tempBitmap,
desiredWidth, desiredHeight, true);
tempBitmap.recycle();
} else {
bitmap = tempBitmap;
}
} if (bitmap == null) {
return Response.error(new ParseError(response));
} else {
return Response.success(bitmap, HttpHeaderParser.parseCacheHeaders(response));
}
}

所以,假设我们自己定义一个Request的话,我们就要去实现我们自己的逻辑。比方是获取视频的话。就会去对数据进行解码等。

在上面的方法实现中,我们能够看到,最后都是通过Response.success方法返回一个Response对象,而这个Response对象是怎么用的呢。就要看以下deliverResponse方法了。

2)deliverResponse

在NetworkDispatcher线程中,当从网络中获取到数据,并通过请求的parseNetworkResponse方法解析之后。会返回一个Reponse对象,这个时候。就会调用Executor来将这个请求post回主线程,例如以下:

mDelivery.postResponse(request, response);

而mDelivery中的postResponse方法事实上是另起一个新线程来调用Request的deliverResponse方法,在ExecutorDelivery类中:

public void postResponse(Request<?

> request, Response<?

> response, Runnable runnable) {
request.markDelivered();
request.addMarker("post-response");
mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
}

ResponseDeliveryRunnable类的run方法中,我们能够看到:

            // Deliver a normal response or error, depending.
if (mResponse.isSuccess()) {
mRequest.deliverResponse(mResponse.result);
} else {
mRequest.deliverError(mResponse.error);
}

那我们看看StringRequest和ImageRequest中的deliverResponse方法:

private final Response.Listener<Bitmap> mListener;
...
@Override
protected void deliverResponse(Bitmap response) {
mListener.onResponse(response);
}

我们能够看到,事实上都是调用一个Response.Listener类的onResponse方法。而事实上这个Listener。则是我们在创建请求的时候才实现,并传进来的,如前面Demo中创建JsonObjectRequest和ImageRequest的时候:

ImageRequest imgRequest = new ImageRequest(imgUrl,
new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap arg0) {
// TODO Auto-generated method stub
imageView.setImageBitmap(arg0);
}
},
100,
100,
Config.ARGB_8888,
new ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
imageView.setImageResource(R.drawable.ic_launcher);
}
});

如上面new Reponse.Listener方法中的实现,非常显然。之所以这么做的原因在于仅仅有调用者才知道怎么去处理Request解析过的数据。

而从这里。我们也能够知道在Reponse类中。就会定义这么一个接口,例如以下,是Volley中Response类的定义:

public class Response<T> {

    /** Callback interface for delivering parsed responses. */
public interface Listener<T> {
/** Called when a response is received. */
public void onResponse(T response);
}

而除了这个接口的定义。另一个ErrorListener接口的定义就不列出来了。而除此之外,Response类中就存放了CacheEntry等信息,相对来说,由于定义了这种Listener接口,Response类是相对照较简单的。

好了。到这里,总结一下:

1)创建一个Request的时候,会同一时候设置一个Response.Listener作为请求的一个參数变量,之后调用RequestQueue的add方法将其加入到Queue。

2)在Queue中的请求会由NetworkDispatcher去跟网络进行通信(假设有缓存的时候,就是CacheDispatcher)。

3)当请求结果回来的时候。Request会首先调用parseNetworkResponse根据不同的请求类型的方法,如Json,Image等不同的处理。

4)什么时候Request经过分析。获得Reponse对象,它将被制成ResponseDelivery从一个线程类新,调用1)在步Listener对于处理。

结束。

Android有关Volley使用(十)至Request和Reponse意识的更多相关文章

  1. Android - 使用Volley请求网络数据

    Android - 使用Volley请求网络数据 Android L : Android Studio 14 个人使用volley的小记,简述使用方法,不涉及volley源码 准备工作 导入Volle ...

  2. [android]-如何在向服务器发送request时附加已保存的cookie数据

    [android]-如何在向服务器发送request时附加已保存的cookie数据 应用场景:在开发android基于手机端+服务器端的应用时,登陆->获取用户信息->获取授权用户相关业务 ...

  3. Android 5.0(棒棒糖))十大新特性

    Android 5.0(棒棒糖))十大新特性 1. 全新Material Design设计风格 Android Lollipop全新的设计语言是受到了多种因素影响,是一种大胆的平面化创新.换句话说,谷 ...

  4. Android图表库MPAndroidChart(十四)——在ListView种使用相同的图表

    Android图表库MPAndroidChart(十四)--在ListView种使用相同的图表 各位好久不见,最近挺忙的,所有博客更新的比较少,这里今天说个比较简单的图表,那就是在ListView中使 ...

  5. Android图表库MPAndroidChart(十二)——来点不一样的,正负堆叠条形图

    Android图表库MPAndroidChart(十二)--来点不一样的,正负堆叠条形图 接上篇,今天要说的,和上篇的类似,只是方向是有相反的两面,我们先看下效果 实际上这样就导致了我们的代码是比较类 ...

  6. Android图表库MPAndroidChart(十)——散点图的孪生兄弟气泡图

    Android图表库MPAndroidChart(十)--散点图的孪生兄弟气泡图 起泡图和散点图如出一辙,但是个人认为要比散点图好看一点,我们来看下实际的演示效果 这个和散点图的实现很相似,我们一起来 ...

  7. Android特效专辑(十二)——仿支付宝咻一咻功能实现波纹扩散特效,精细小巧的View

    Android特效专辑(十二)--仿支付宝咻一咻功能实现波纹扩散特效,精细小巧的View 先来看看这个效果 这是我的在Only上添加的效果,说实话,Only现在都还只是半成品,台面都上不了,怪自己技术 ...

  8. Android特效专辑(十)——点击水波纹效果实现,逻辑清晰实现简单

    Android特效专辑(十)--点击水波纹效果实现,逻辑清晰实现简单 这次做的东西呢,和上篇有点类似,就是用比较简单的逻辑思路去实现一些比较好玩的特效,最近也是比较忙,所以博客更新的速度还得看时间去推 ...

  9. Android UI开发第二十八篇——Fragment中使用左右滑动菜单

    Fragment实现了Android UI的分片管理,尤其在平板开发中,好处多多.这一篇将借助Android UI开发第二十六篇——Fragment间的通信. Android UI开发第二十七篇——实 ...

随机推荐

  1. 关于java socket(转)

    1. 关于new Socket()中参数的理解 Server端: 调用ServerSocket serverSocket = new ServerSocket(1287,2);后Server端打开了指 ...

  2. Installing IIS 8.5 on Windows Server 2012 R2

    原文 Installing IIS 8.5 on Windows Server 2012 R2 Introduction This document describes how to install ...

  3. deepinmind(转)

    http://it.deepinmind.com/ 花名有孚,支付宝工程师 有希望加入支付宝的同学,可以把简历发到我的个人邮箱spidercoco@gmail.com

  4. 设计模式 - 迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释

    迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考迭代器模式(ite ...

  5. Oracle按不同时间分组统计

    Oracle按不同时间分组统计 Oracle按不同时间分组统计的sql 如下表table1: 日期(exportDate) 数量(amount) -------------- ----------- ...

  6. C++ 虚函数表决心

    C++ 虚函数表解析 xml:namespace prefix = o /> 陈皓 http://blog.csdn.net/haoel 前言 C++中的虚函数的作用主要是实现了多态的机制. 关 ...

  7. [置顶] 纯手工打造漂亮的瀑布流,五大插件一个都不少Bootstrap+jQuery+Masonry+imagesLoaded+Lightbox!

    前两天写的文章<纯手工打造漂亮的垂直时间轴,使用最简单的HTML+CSS+JQUERY完成100个版本更新记录的华丽转身!>受到很多网友的喜爱,今天特别推出姊妹篇<纯手工打造漂亮的瀑 ...

  8. 深入了解Libgdx中间Skin分类

    文不是直接翻译.. . 本文在Libgdx的官方wiki的基础上,加上一些自己的理解.所以,难免会一些甚至是非常多的理解非常片面的东西.写的不好,还请见谅.... 事实上 事实上.在LibGDX的官方 ...

  9. 如何构建高性能web网站:分布式缓存

    一.数据库前端缓冲区 要清除数据库前缓冲区,首先必须明确什么是文件系统的内核缓冲区(Buffer Area):它位于内核的物理内存地址空间,除了使用O_DIRECT比其他标签中打开文件,所有的磁盘的读 ...

  10. Nlog 配置总结

    Writes log messages to one or more files. Since NLog 4.3 the ${basedir} isn't needed anymore for rel ...