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

[Volley+Gson]获取PM2.5小应用(二)/自定义Volley Request

2016-01-05 21:54 435 查看
上一篇文章 [Volley+Gson]获取PM2.5小应用,我们介绍了使用Volley+Gson来获取并解析Json数据,我们使用的是JsonObjectRequest这个libs自带的方法,考虑到许多API都是使用Json数据,那我们何不把Gson一起打包到Request中,方便快捷!~那么我们接下来就来自定义一个可以获取+解析Json数据的Volley
Requst

我们先找下参照物,上一篇文章我们使用的是JsonObjectRequest,而JsonObjectRequest是继承自抽象类 JsonRequest,JsonRequest定义如下:

public abstract class JsonRequest<T> extends Request<T> {
private static final String PROTOCOL_CHARSET = "utf-8";
private static final String PROTOCOL_CONTENT_TYPE = String.format("application/json; charset=%s", new Object[]{"utf-8"});
private final Listener<T> mListener;
private final String mRequestBody;

/** @deprecated */
public JsonRequest(String url, String requestBody, Listener<T> listener, ErrorListener errorListener) {
this(-1, url, requestBody, listener, errorListener);
}

public JsonRequest(int method, String url, String requestBody, Listener<T> listener, ErrorListener errorListener) {
super(method, url, errorListener);
this.mListener = listener;
this.mRequestBody = requestBody;
}

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

protected abstract Response<T> parseNetworkResponse(NetworkResponse var1);

}


抽象方法 parseNetWorkResponse 在 JsonObjectRequest.class 定于:

protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String je = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(je), HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException var3) {
return Response.error(new ParseError(var3));
} catch (JSONException var4) {
return Response.error(new ParseError(var4));
}
}
需要注意两点

1. JsonRequest 继承 Request 类,使用JsonRequest最终需要把参数通过supper传给父类,完成Http操作
2. 主要功能在于deliverResponse()以及parseNetworkResponse()这两个方法的实现,deliverResponse()调用了mListener中的onResponse()方法,并将response内容传入,以完成OnResponse的回调。parseNetworkResponse()则对服务器响应的数据进行解析,也就是我们今天使用Gson对Json数据进行解析的关键

public class GsonRequest<T> extends Request<T> {
private final Response.Listener<T> mListener;
private Gson mGson = new Gson();
private Class<T> mClass;
private Map<String,String> mHeaders;

// supprot Method and header modication
public GsonRequest(int method, String url,Response.Listener<T> mListener,
Response.ErrorListener errorlistener, Map<String, String> mHeaders, Class<T> mClass) {
super(method, url, errorlistener);
this.mListener = mListener;
this.mHeaders = mHeaders;
this.mClass = mClass;
}

// do not modfiy the header
public GsonRequest(int method, String url, Response.Listener<T> mListener,
Response.ErrorListener errorlistener,Class<T> mClass) {
super(method, url, errorlistener);
this.mListener = mListener;
this.mHeaders = null;
this.mClass = mClass;
}

// Get Method and Support header modication
public GsonRequest(String url,Response.Listener<T> mListener,
Response.ErrorListener errorlistener, Map<String, String> mHeaders, Class<T> mClass) {
super(Method.GET, url, errorlistener);
this.mListener = mListener;
this.mHeaders = mHeaders;
this.mClass = mClass;
}

//Get Method and Do not modify the header
public GsonRequest(String url, Response.Listener<T> mListener,
Response.ErrorListener errorlistener,Class<T> mClass) {
super(Method.GET, url, errorlistener);
this.mListener = mListener;
this.mHeaders = null;
this.mClass = mClass;
}

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

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return mHeaders == null? super.getHeaders():mHeaders;
}
@Override
protected void deliverResponse(T response) {
mListener.onResponse(response);
}
}
这里我比较贪心,把Header的信息也一起封装进去,所以就有 有/无Header 是/否Get方法 四种GsonRequest 方法

AqiInfo的定义和上一篇文章一样,不重复贴了

MainActivity的处理,如下

void GetPM25Value(String mCityName) {
String url = httpUrl + "?" + httpArg + mCityName; //make the url

GsonRequest<AqiInfo> request = new GsonRequest<AqiInfo>(url,new Response.Listener<AqiInfo>() {
@Override
public void onResponse(AqiInfo aqiInfo) {
if (aqiInfo.retData != null){
String mTime = aqiInfo.retData.time.substring(11,19);
mTv.setText(aqiInfo.retData.toString()+"time : "+ mTime + ",Today ");
} else {
mTv.setText("Can not Get Any Data From the Server");
}
}
} ,new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if(error.toString().contains("UnknownHostException")) {
mTv.setText("Plz Connect the NetWork and Try Again ^.^");
} else {
mTv.setText("Sorry , Do not support this City T.T");
}
}
},mheader,AqiInfo.class);

mQueue.add(request);
}
其中,传入的参数 mheader 定义:

Map<String,String> mheader;
mheader = new HashMap<>();
mheader.put("apikey","您的用户apkapi");
将用户apikey传入,界面和上次一样,不贴咯~

然后发生了个 Warning



Signals places wherer an unchecked warning is issued by the compiler
很头疼,连英文都看不懂=。=,最后在Stack OverFlow找到答案 :
传送门

原来是我在引用GsonRequest的时候没初始化好

错误:

GsonRequest<AqiInfo> request = new GsonRequest(url,new Response.Listener<AqiInfo>()...
正确

GsonRequest<AqiInfo> request = new GsonRequest<AqiInfo>(url,new Response.Listener<AqiInfo>()...
类型不匹配导致的错误,参数一多,眼就花了 @。@

参考文章

Android Volley完全解析(三),定制自己的Request(强烈推荐)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息