[关闭]
@946898963 2018-05-18T12:11:34.000000Z 字数 4771 阅读 1065

Volley-JsonRequest及其两个子类的源码解析

Android控件跟框架 Android源码分析


建议先阅读:Volley-Request的源码解析

JsonRequest是Request的子类,不过JsonRequest仍然是一个抽象类,并不能直接创建他的子类,他提供了两个子类JsonRequest和JsonRequest,我们会在后面对他们进行介绍。相比于Request,JsonRequest只是重写了他的几个post相关方法。

JsonRequest源码解析

成员变量:

  1. private final Listener<T> mListener;
  2. private final String mRequestBody;

Listener是Response中定义的的一个接口

  1. public class Response<T> {
  2. ....
  3. public interface Listener<T> {
  4. public void onResponse(T response);
  5. }
  6. ....
  7. }

我们创建Listener的子类,重写其onResponse的方法,在onRespons方法中,对请求返回的T类型的数据进行处理。

mListener.onResponse(T response)是在deliverResponse中被调用的,而deliverResponse方法则是在ExecutorDelivery中被调用的,这个调用是发生在主线程的,所以我们可以在onResponse方法中操作UI,详细过程建议阅读:Volley-ResponseDelivery及其实现类的源码解析

构造方法:

  1. public JsonRequest(String url, String requestBody, Listener<T> listener,
  2. ErrorListener errorListener) {
  3. this(Method.DEPRECATED_GET_OR_POST, url, requestBody, listener, errorListener);
  4. }
  5. public JsonRequest(int method, String url, String requestBody, Listener<T> listener,
  6. ErrorListener errorListener) {
  7. super(method, url, errorListener);
  8. mListener = listener;
  9. mRequestBody = requestBody;
  10. }

构造方法就是对成员变量进行简单的赋值操作。

post相关方法

  1. protected static final String PROTOCOL_CHARSET = "utf-8";
  2. private static final String PROTOCOL_CONTENT_TYPE =
  3. String.format("application/json; charset=%s", PROTOCOL_CHARSET);
  4. @Override
  5. public String getPostBodyContentType() {
  6. return getBodyContentType();
  7. }
  8. @Override
  9. public byte[] getPostBody() {
  10. return getBody();
  11. }
  12. @Override
  13. public String getBodyContentType() {
  14. return PROTOCOL_CONTENT_TYPE;
  15. }
  16. @Override
  17. public byte[] getBody() {
  18. try {
  19. return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET);
  20. } catch (UnsupportedEncodingException uee) {
  21. VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
  22. mRequestBody, PROTOCOL_CHARSET);
  23. return null;
  24. }
  25. }

在介绍request的时候,已经在post相关方法小节对这几个方法的调用流程进行了介绍,这里就不再介绍了,直接阅读Volley-Request的源码解析post相关方法小节即可。

只用当我们用post方式提交数据的时候,getBody和getBodyContentType() 方法才会被调用。

getBody是按照“utf-8”编码方式获得字符串的字节数组。而getBodyContentType()是设置了post方式提交json数据的时候的“content-type首部”。

JsonRequest源码解析

JsonRequest是JsonRequest的子类,请求的数据,以JSONObject的形式返回。

构造方法

  1. public JsonObjectRequest(int method, String url, JSONObject jsonRequest,
  2. Listener<JSONObject> listener, ErrorListener errorListener) {
  3. super(method, url,(jsonRequest==null)?null:jsonRequest.toString(),listener,errorListener);
  4. }
  5. public JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener,
  6. ErrorListener errorListener) {
  7. this(jsonRequest == null ? Method.GET : Method.POST, url, jsonRequest,listener, errorListener);
  8. }

构造方式就是简单的对成员变量进行赋值,可以看到当我们向服务器提交JSONObject数据的时候,默认会以post请求方式进行提交。

parseNetworkResponse方法

最主要的是parseNetworkResponse方法,parseNetworkResponse方法会对NetworkResponse进行解析,返回我们需要的JSONObject类型的Response,如果我们想要定义自己的Request的话,就需要重写这个方法,将NetworkResponse解析成我们想要的类型的Response。这个方法是在NetworkDispatcher的run方法中被调用的,关于NetworkDispatcher,建议阅读:Volley-NetworkDispatcher源码解析

  1. @Override
  2. protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
  3. try {
  4. String jsonString = new String(response.data,
  5. HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
  6. return Response.success(new JSONObject(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. }

在该方法中首先按照响应首部中的编码方式(也就是服务器端对数据的编码方式),将服务器返回的数据转换成字符串。

parseCharset的作用是从服务器返回的“content-type”响应首部中解析出数据的编码方式,如果解析不到的话,就使用默认的编码方式“ISO-8859-1”。

然后利用得到的字符串创建一个JSONObject对象,利用该JSONObject对象和解析NetworkResponse对象得到的Cache.Entry对象,包装成一个Response对象返回。

parseCacheHeaders(response)的作用就是对NetworkResponse进行解析,生成一个Cache.Entry对象。

关于parseCharset方法和parseCacheHeaders方法,建议阅读:Volley-HttpHeaderParser源码解析

JsonRequest源码解析

JsonRequest是JsonRequest的子类,请求的数据,以JSONArray的形式返回。

构造方法

  1. public JsonArrayRequest(String url, Listener<JSONArray> listener, ErrorListener errorListener) {
  2. super(Method.GET, url, null, listener, errorListener);
  3. }
  4. public JsonArrayRequest(int method, String url, JSONArray jsonRequest,
  5. Listener<JSONArray> listener, ErrorListener errorListener) {
  6. super(method, url,(jsonRequest==null)?null:jsonRequest.toString(),listener,errorListener);
  7. }

构造方式就是简单的对成员变量进行赋值。

parseNetworkResponse方法

最主要的是parseNetworkResponse方法,parseNetworkResponse方法会对NetworkResponse进行解析,返回我们需要的JSONArray类型的Response。

  1. @Override
  2. protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
  3. try {
  4. String jsonString = new String(response.data,
  5. HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
  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. }

在该方法中首先按照响应首部中的编码方式(也就是服务器端对数据的编码方式),将服务器返回的数据转换成字符串。

然后利用得到的字符串创建一个JSONArray对象,利用该JSONArray对象和解析NetworkResponse对象得到的Cache.Entry对象,包装成一个Response对象返回。

相关Java知识:
JSONObject与JSONArray的理解

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注