小结Volley中Response从接收到转换成业务的过程
parseNetworkResponse()
是对Response进行第一步的解析——
把服务器的响应数据
组织成对应类型Request
的类型
的Response;
- 然后这个Response会传给
Response.success()
,
Response.success(xmlPullParser, HttpHeaderParser.parseCacheHeaders(response));
- 接着会在
deliverResponse()
中将这个
response
传给mListener.onResponse()
,
即mListener.onResponse(response);
- 在使用的时候,
我们常规操作是实例化一个
类型Request
,
实例化时(new过程)传给了构造方法的
是一个重写了onResponse()
的Listener<对应类型>实例
,
也就是说,
**我们在实例化一个类型Request
的时候,
重写onResponse()
,**
**在onResponse()
其中,
对Response
进行了第二次解析
——**
**即,把首次解析组织好的数据/对象
提现成具体的业务实现;
这里`@Override
public void onResponse(对应类型response)`的`onResponse(对应类型response)`和
我们自己实例化
构造的Listener
:new Response.Listener<对应类型>(){@Override...}
,
其实跟框架源码中deliverResponse()
中 mListener.onResponse(response);
的Listener、onResponse、response
逻辑上是对应的;**
- **话不多说,理解了这个几个泛型之间的联系,
也就能把Volley框架中自定义Request的步骤过程和原理理解个七七八八;
下面围绕泛型之间的联系展开笔记,
同时关联到了Volley中Response从接收到转换成业务的过程描述;**
首先看下StringRequest的源码,如下所示:
/**
* A canned request for retrieving the response body at a given URL as a String.
*/
public class StringRequest extends Request<String> {
private final Listener<String> mListener;
/**
* Creates a new request with the given method.
*
* @param method the request {@link Method} to use
* @param url URL to fetch the string at
* @param listener Listener to receive the String response
* @param errorListener Error listener, or null to ignore errors
*/
public StringRequest(int method, String url, Listener<String> listener,
ErrorListener errorListener) {
super(method, url, errorListener);
mListener = listener;
}
/**
* Creates a new GET request.
*
* @param url URL to fetch the string at
* @param listener Listener to receive the String response
* @param errorListener Error listener, or null to ignore errors
*/
public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {
this(Method.GET, url, listener, errorListener);
}
@Override
protected void deliverResponse(String response) {
mListener.onResponse(response);
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String parsed;
try {
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}
}
- 类型Request源码中的parseNetworkResponse()
是对Response进行第一步的解析——
把服务器的响应数据
组织成对应类型Request
的类型
的Response,
如:
- ```StringRequest```中的```parseNetworkResponse()```
把服务器的响应数据组织成String
类型,Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
( Response<String> parseNetworkResponse(NetworkResponse response),String parsed);
ImageRequest
是bitmap
:Response.success(bitmap, HttpHeaderParser.parseCacheHeaders(response));
(Response<Bitmap> parseNetworkResponse(NetworkResponse response) )
XMLRequest
是XmlPullParser
Response<XmlPullParser> parseNetworkResponse(NetworkResponse response)
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String parsed;
try {
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}
- 然后这个Response会传给
Response.success()
,
Response.success(xmlPullParser, HttpHeaderParser.parseCacheHeaders(response));
- 接着会在deliverResponse()中
将这个response
传给mListener.onResponse()
@Override
protected void deliverResponse(String response) {
mListener.onResponse(response);
}
- 在实例化一个
类型Request
的时候,
我们传给了构造方法一个重写了onResponse()
的Listener<对应类型>
,
也就是说,
**我们在实例化一个类型Request
的时候,
在重写的onResponse()
中,**
对Response
进行了第二次解析
——
**即,把首次解析组织好的数据/对象
提现成具体的业务实现;**
下面是XMLRequest的自定义代码与使用例程:
- 使用例程:
XMLRequest xmlRequest = new XMLRequest(
"http://flash.weather.com.cn/wmaps/xml/china.xml",
new Response.Listener<XmlPullParser>() {
@Override
public void onResponse(XmlPullParser response) {
try {
int eventType = response.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
String nodeName = response.getName();
if ("city".equals(nodeName)) {
String pName = response.getAttributeValue(0);
Log.d("TAG", "pName is " + pName);
reponseContent += pName;
reponseContent += "\n";
}
break;
}
eventType = response.next();
}
oriString = new String(reponseContent.getBytes("ISO-8859-1"), "utf-8");
responseText.setText(oriString);
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG", error.getMessage(), error);
}
});
mQueue.add(xmlRequest);
- XMLRequest的自定义代码:
public class XMLRequest extends Request<XmlPullParser> {
private final Listener<XmlPullParser> mListener;
public XMLRequest(int method, String url, Listener<XmlPullParser> listener,
ErrorListener errorListener) {
super(method, url, errorListener);
mListener = listener;
}
public XMLRequest(String url, Listener<XmlPullParser> listener, ErrorListener errorListener) {
this(Method.GET, url, listener, errorListener);
}
@Override
protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) {
try {
String xmlString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
xmlPullParser.setInput(new StringReader(xmlString));
return Response.success(xmlPullParser, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (XmlPullParserException e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(XmlPullParser response) {
mListener.onResponse(response);
}
}
附上写demo时候遇到的两个bug,以及相关的解决办法的文章:
网络安全配置问题:xml解析结果乱码
解决方法:new String(reponseContent.getBytes("ISO-8859-1"), "utf-8");
相关文章:
- **小结一下,
总而言之我们可以看到,public class XMLRequest extends Request<XmlPullParser>
中Request<XmlPullParser>
的泛型,protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response)
中Response<XmlPullParser>
的泛型,private final Listener<XmlPullParser> mListener;
中Listener<XmlPullParser>
的泛型,
都是一致的,
是因,**
- **```Request<XmlPullParser>```的泛型指定自定义二级Request的类型,**
- **```Response<XmlPullParser>```的泛型表明
parseNetworkResponse()进行第一步解析的返回结果类型,
把服务器的响应数据组织成对应类型Request
的类型;**
- **```Listener<XmlPullParser>```的泛型
对应着Listener
传递的Response的类型,
也即表明二次解析提现业务时的操作对象(即Response,第一步解析的返回结果类型)
也即onResponse()
的参数类型**
- 另外,
自定义Gson的时候,因为类型不明确,所以用T占位,
使用时用对应的类作为参数即可:
如例程:Response.success(mGson.fromJson(jsonString, mClass)
中mGson.fromJson(jsonString, mClass)
的mClass(private Class<T> mClass;)
对应gson.fromJson(jsonData, new TypeToken<List<T>>(){}.getType());
中的new TypeToken<List<T>>(){}.getType()