您的位置:首页 > 产品设计 > UI/UE

Volley的高级用法(自定义Request)

2015-12-10 10:34 417 查看
1. 自定义XMLRequest

下面我们自定义一个XMLRequest,用于请求一条XML格式的数据。从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));
}
}


首先StringRequest是继承自Request类的,Request可以指定一个泛型类,这里指定的当然就是String了,接下来StringRequest中

提供了两个有参的构造函数,参数包括请求类型,请求地址,以及响应回调等,但需要注意的是,在构造函数中一定要调用super()

方法将这几个参数传给父类,因为HTTP的请求和响应都是在父类中自动处理的。

由于Request类中的deliverResponse()和parseNetworkResponse()是两个抽象方法,因此StringRequest中需要对这两个方法进行实现。

deliverResponse()方法中的实现很简单,仅仅是调用了mListener中的onResponse()方法,并将response内容传入即可,这样就可以将

服务器响应的数据进行回调了。arseNetworkResponse()方法中则应该对服务器响应的数据进行解析,其中数据是以字节的形式存放在

NetworkResponse的data变量中的,这里将数据取出然后组装成一个String,并传入Response的success()方法中即可。

所以我们自定义XMlRequest的仿照StringRequest实现如下:

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);
}

}
上例中XMLRequest也是继承自Request类的,只不过这里指定的泛型类是XmlPullParser,说明我们准备使用Pull解析的方式来解析XML。

parseNetworkResponse()方法中,先是将服务器响应的数据解析成一个字符串,然后设置到XmlPullParser对象中,在deliverResponse()方法中则是将XmlPullParser对象进行回调。

确定接口后,按照以下的方式来使用XMLRequest即可:

XMLRequest xmlRequest = new XMLRequest(
"http://www.device.com.cn/data/device.html",
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);
}
break;
}
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的实例,并把服务器接口地址传入,然后在onResponse()方法中解析响应的XML数据

2. 自定义GsonRequest

首先我们需要把gson的jar包添加到项目当中,接着定义一个GsonRequest继承自Request,代码如下所示:

public class GsonRequest<T> extends Request<T> {

private final Listener<T> mListener;

private Gson mGson;

private Class<T> mClass;

public GsonRequest(int method, String url, Class<T> clazz, Listener<T> listener,
ErrorListener errorListener) {
super(method, url, errorListener);
mGson = new Gson();
mClass = clazz;
mListener = listener;
}

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

@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(mGson.fromJson(jsonString, mClass),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}

@Override
protected void deliverResponse(T response) {
mListener.onResponse(response);
}

}
接下来我们使用对象的方式将这段JSON字符串表示出来。新建一个Device类,代码如下所示:

public class Device {

private DeviceInfo deviceinfo;

public DeviceInfo getDeviceinfo() {
return deviceinfo;
}

public void setDeviceinfo(DeviceInfo deviceinfo) {
this.deviceinfo = deviceinfo;
}

}
Device类中只是引用了DeviceInfo这个类。接着新建DeviceInfo类,代码如下所示:

public class DeviceInfo {

private String username;

private String sn;

private String avgoil;

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getSn() {
return sn;
}

public void setSn(String sn) {
this.sn = sn;
}

public String getAvgoil() {
return avgoil;
}

public void setAvgoil(String avgoil) {
this.avgoil= avgoil;
}

}
DeviceInfo类中含有username、sn、agoil这几个字段。下面就是如何调用GsonRequest了,代码如下所示:
GsonRequest<Device> gsonRequest = new GsonRequest<Device>(
"http://www.device.com.cn/data/device.html", Device.class,
new Response.Listener<Device>() {
@Override
public void onResponse(Device device) {
DeviceInfo deviceInfo = device.getDeviceinfo();
Log.d("TAG", "username is " + deviceInfo.getUsername());
Log.d("TAG", "sn is " + deviceInfo.getSn());
Log.d("TAG", "getAvgoil is " + deviceInfo.getAvgoil());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG", error.getMessage(), error);
}
});
mQueue.add(gsonRequest);
这里onResponse()方法的回调中直接返回了一个Device对象,我们通过它就可以得到DeviceInfo对象,接着就能从中取出JSON中的相关数据了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: