Android网络框架-Volley(五) 使用Volley发送自定义Request

时间:2022-12-13 19:49:02

自定义一个Request

Volley已经帮我们实现好了StringRequest、JsonObjectRequest、JsonArrayRequest以及ImageRequest。如果我们想要发送一个xml请求,我们可以自定义一个Request。自定义一个Request我们需要:
1. 继承Request,其中泛型T就是我们想要解析的格式,
2. 重写parseNetworkResponse()和deliverResponse()方法

parseNetworkResponse()

我们可以先来看一看StringRequest请求是怎么重写的parseNetworkResponse()方法

//Response<T>中的泛型为String
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String parsed;
try {
//response.data就是返回结果的数据部分
//response.headers就是返回结果的数据头部分
//这里进行第一步加工,将结果经过编码后加工成一个字符串
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
//这里进行第二步加工,在Response.success中我们将返回已经加工好的数据,第一个参数是我们自定义请求的类型,这里就是String,所以不用再进行加工了,第二个参数是解析cache的头部信息,可以知道这条数据的ttl等信息,用来交给CacheDispatcher判断是否过期等等。
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}

deliverResponse

这个方法非常简单,记住就可以了。

 @Override
protected void deliverResponse(String response) {
//仅仅调用了Listener接口中的onResponse方法
mListener.onResponse(response);
}

好了,现在我们自定义一个XmlRequest,Volley没有给我们提供XmlRequest,我们可以自己写一个,加到我们的Volley中,打造我们自己的Volley框架

//新建一个XmlRequest继承自Request<T> 其中泛型是XmlPullParser
public class XmlRequest extends Request<XmlPullParser> {
//Listener接口
private final Listener<XmlPullParser> mListener;
//构造方法,其中参数我们应该都很清楚了
public XMLRequest(int method, String url, Listener<XmlPullParser> listener,
ErrorListener errorListener) {
super(method, url, errorListener);
mListener = listener;
}
//默认为get请求方式的构造方法
public XMLRequest(String url, Listener<XmlPullParser> listener, ErrorListener errorListener) {
this(Method.GET, url, listener, errorListener);
}
//parseNetworkResponse方法
@Override
protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) {
try {
//第一步加工,将得到的数据转为一个字符串
String xmlString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
//这些固定代码就写在这里,以便于我们在使用XmlRequest的时候,只需要关注我们如何去解析获得的xml数据就可以了
//第一步加工,将得到的数据转为一个字符串
String xmlString = new String(response.data,HttpHeaderParser.parseCharset(response.headers));
//这些固定代码就写在这里,以便于我们在使用XmlRequest的时候,只需要关注我们如何去解析获得的xml数据就可以了
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new StringReader(xmlString));
//第二步加工。直接返回这个xmlPullPaser
return Response.success(parser, HttpHeaderParser.parseCacheHeaders(response)); catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (XmlPullParserException e) {
return Response.error(new ParseError(e));
}
}
//deliverResponse方法,直接固定一句话
@Override
protected void deliverResponse(XmlPullParser response) {
mListener.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) {

//解析xml数据,后面我们会介绍如何自己打造万能xml解析方法
eventType = response.next();
}
} 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就定义完成了,我们可以加到Volley中,以后就可以直接拿来就用了。
谷歌官方还给出了一个自定义GsonRequest的例子,其实和我们自定义XmlRequest是一样的,我们来看一看他是怎么实现的。

public class GsonRequest<T> extends Request<T> {
//新建一个Gson
private final Gson gson = new Gson();
//解析出来的json数据就保存到这个实体类中
private final Class<T> clazz;
//请求的头部信息,这个视服务器而定,有些服务器需要传一些固定的头部信息
private final Map<String, String> headers;
//Listener接口
private final Listener<T> listener;

/**
* 构造方法
*
* @param url 请求的url地址
* @param clazz 实体类
* @param headers 头部信息
*/

public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
Listener<T> listener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.clazz = clazz;
this.headers = headers;
this.listener = listener;
}

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
// deliverResponse方法,再一次印证,这就是个固定的写法
@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
//parseNetworkResponse方法
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
//第一步加工,将获得的数据编码后变成字符串
String json = new String(
response.data,
HttpHeaderParser.parseCharset(response.headers));
//第二步加工,第一个参数调用gson.fromJson,将解析到的数据保存到实体类中,第二个参数是cache头部信息
return Response.success(
gson.fromJson(json, clazz),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
}

这样一个GsonRequest就定义完了,和我们的XmlRequest基本一样,Volley是非常灵活的,我们可以根据我们自己的需求,定制我们的Volley框架。在下一篇文章中,我们将介绍如何打造一款属于我们自己的xml解析框架,任何形式的xml数据我们都不怕。