建议先阅读:Volley-Request的源码解析。
JsonRequest是Request的子类,不过JsonRequest仍然是一个抽象类,并不能直接创建他的子类,他提供了两个子类JsonRequest和JsonRequest,我们会在后面对他们进行介绍。相比于Request,JsonRequest只是重写了他的几个post相关方法。
JsonRequest源码解析
成员变量:
1 2
| private final Listener<T> mListener; private final String mRequestBody;
|
- mListener,传入的接收响应结果的回调接口。
- mRequestBody,使用post方式提交数据的时候的json字符串。
Listener是Response中定义的的一个接口
1 2 3 4 5 6 7
| public class Response<T> { .... public interface Listener<T> { public void onResponse(T response); } .... }
|
我们创建Listener的子类,重写其onResponse的方法,在onRespons方法中,对请求返回的T类型的数据进行处理。
mListener.onResponse(T response)是在deliverResponse中被调用的,而deliverResponse方法则是在ExecutorDelivery中被调用的,这个调用是发生在主线程的,所以我们可以在onResponse方法中操作UI,详细过程建议阅读:Volley-ResponseDelivery及其实现类的源码解析。
构造方法:
1 2 3 4 5 6 7 8 9 10 11
| public JsonRequest(String url, String requestBody, Listener<T> listener, ErrorListener errorListener) { this(Method.DEPRECATED_GET_OR_POST, url, requestBody, listener, errorListener); }
public JsonRequest(int method, String url, String requestBody, Listener<T> listener, ErrorListener errorListener) { super(method, url, errorListener); mListener = listener; mRequestBody = requestBody; }
|
构造方法就是对成员变量进行简单的赋值操作。
post相关方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| protected static final String PROTOCOL_CHARSET = "utf-8";
private static final String PROTOCOL_CONTENT_TYPE = String.format("application/json; charset=%s", PROTOCOL_CHARSET); @Override public String getPostBodyContentType() { return getBodyContentType(); }
@Override public byte[] getPostBody() { return getBody(); }
@Override public String getBodyContentType() { return PROTOCOL_CONTENT_TYPE; }
@Override public byte[] getBody() { try { return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET); } catch (UnsupportedEncodingException uee) { VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", mRequestBody, PROTOCOL_CHARSET); return null; } }
|
在介绍request的时候,已经在post相关方法小节对这几个方法的调用流程进行了介绍,这里就不再介绍了,直接阅读Volley-Request的源码解析的post相关方法小节即可。
只用当我们用post方式提交数据的时候,getBody和getBodyContentType() 方法才会被调用。
getBody是按照“utf-8”编码方式获得字符串的字节数组。而getBodyContentType()是设置了post方式提交json数据的时候的“content-type首部”。
JsonRequest’<‘JSONObject‘>’源码解析
JsonRequest是JsonRequest的子类,请求的数据,以JSONObject的形式返回。
构造方法
1 2 3 4 5 6 7 8
| public JsonObjectRequest(int method, String url, JSONObject jsonRequest, Listener<JSONObject> listener, ErrorListener errorListener) { super(method, url,(jsonRequest==null)?null:jsonRequest.toString(),listener,errorListener); } public JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener, ErrorListener errorListener) { this(jsonRequest == null ? Method.GET : Method.POST, url, jsonRequest,listener, errorListener); }
|
构造方式就是简单的对成员变量进行赋值,可以看到当我们向服务器提交JSONObject数据的时候,默认会以post请求方式进行提交。
parseNetworkResponse方法
最主要的是parseNetworkResponse方法,parseNetworkResponse方法会对NetworkResponse进行解析,返回我们需要的JSONObject类型的Response,如果我们想要定义自己的Request的话,就需要重写这个方法,将NetworkResponse解析成我们想要的类型的Response。这个方法是在NetworkDispatcher的run方法中被调用的,关于NetworkDispatcher,建议阅读:Volley-NetworkDispatcher源码解析。
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Override protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) { try { String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET)); 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)); } }
|
在该方法中首先按照响应首部中的编码方式(也就是服务器端对数据的编码方式),将服务器返回的数据转换成字符串。
parseCharset的作用是从服务器返回的“content-type”响应首部中解析出数据的编码方式,如果解析不到的话,就使用默认的编码方式“ISO-8859-1”。
然后利用得到的字符串创建一个JSONObject对象,利用该JSONObject对象和解析NetworkResponse对象得到的Cache.Entry对象,包装成一个Response对象返回。
parseCacheHeaders(response)的作用就是对NetworkResponse进行解析,生成一个Cache.Entry对象。
关于parseCharset方法和parseCacheHeaders方法,建议阅读:Volley-HttpHeaderParser源码解析。
JsonRequest‘<’JSONArray‘>’源码解析
JsonRequest是JsonRequest的子类,请求的数据,以JSONArray的形式返回。
构造方法
1 2 3 4 5 6 7 8
| public JsonArrayRequest(String url, Listener<JSONArray> listener, ErrorListener errorListener) { super(Method.GET, url, null, listener, errorListener); } public JsonArrayRequest(int method, String url, JSONArray jsonRequest, Listener<JSONArray> listener, ErrorListener errorListener) { super(method, url,(jsonRequest==null)?null:jsonRequest.toString(),listener,errorListener); }
|
构造方式就是简单的对成员变量进行赋值。
parseNetworkResponse方法
最主要的是parseNetworkResponse方法,parseNetworkResponse方法会对NetworkResponse进行解析,返回我们需要的JSONArray类型的Response。
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Override protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) { try { String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET)); return Response.success(new JSONArray(jsonString), HttpHeaderParser.parseCacheHeaders(response)); } catch (UnsupportedEncodingException e) { return Response.error(new ParseError(e)); } catch (JSONException je) { return Response.error(new ParseError(je)); } }
|
在该方法中首先按照响应首部中的编码方式(也就是服务器端对数据的编码方式),将服务器返回的数据转换成字符串。
然后利用得到的字符串创建一个JSONArray对象,利用该JSONArray对象和解析NetworkResponse对象得到的Cache.Entry对象,包装成一个Response对象返回。
相关Java知识:
JSONObject与JSONArray的理解
上一篇:Volley-ImageRequest的源码解析
下一篇:Volley-StringRequest源码解析