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

上一篇文章 [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(强烈推荐)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值