@946898963
2018-05-18T12:11:34.000000Z
字数 4771
阅读 1065
Android控件跟框架
Android源码分析
建议先阅读:Volley-Request的源码解析。
JsonRequest是Request的子类,不过JsonRequest仍然是一个抽象类,并不能直接创建他的子类,他提供了两个子类JsonRequest和JsonRequest,我们会在后面对他们进行介绍。相比于Request,JsonRequest只是重写了他的几个post相关方法。
成员变量:
private final Listener<T> mListener;
private final String mRequestBody;
Listener是Response中定义的的一个接口
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及其实现类的源码解析。
构造方法:
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相关方法
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是JsonRequest的子类,请求的数据,以JSONObject的形式返回。
构造方法
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源码解析。
@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是JsonRequest的子类,请求的数据,以JSONArray的形式返回。
构造方法
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。
@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的理解