android网络请求框架Volley(二)

 1  Volley是用来请求网络数据的,首先我们要准备好要传递的URL参数

HashMap<String, String> params = new HashMap<String, String>();
        params.put("user_id", userId);
        params.put("count", count + "");
        params.put("since_time", timeSince);
        params.put("profile_user_id", profileUserId);
        String url = HttpConstant.DOMAIN_NORMAL + HttpConstant.FRIENDS_FANS_1;

2 把URL拼凑成一个完整的链接

public void get(String url, Map<String, String> data, String tag, final CallbackLightRequest<LightResponse> callback) {
        if (!ConfigRequests.isNetworkOkWithAlert(mContext)) {
            callNetworkError(tag, url, data, callback);
            return;
        }
        Map<String, String> defaultParams = ConfigRequests.getInstance().getDefaultParams();
        if (defaultParams != null && defaultParams.size() > 0) {
            data.putAll(defaultParams);
        }
        if (data != null && data.size() > 0) {
            url = url + "?" + RequestUtils.map2QueryString(data);
        }
        this._get(url, tag, callback);
    }

    拼凑URl的方法:map2QueryString

public class RequestUtils {
    /**
     * 生成QueryString,以 a=1&b=2形式返回
     */
    public static String map2QueryString(Map<String, String> map) {
        StringBuilder sb = new StringBuilder();
        String value;
        try {
            if (map != null && map.size() > 0) {
                for (Entry<String, String> entry : map.entrySet()) {
                    value = "";
                    value = entry.getValue();
                    if (StringUtils.isEmpty(value)) {
                        value = "";
                    } else {
                        value = URLEncoder.encode(value, Models.Encoding.UTF8);
                    }
                    sb.append(entry.getKey()).append("=").append(value)
                            .append("&");
                }
                sb.deleteCharAt(sb.length() - 1);
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

 3 发送请求,并将请求放进Requestqueue中,我把请求统一封装在一个

    AppRequest类中,这个类如下:

private void _get(final String url, final String tag, final Callback callback) {

        LogUtils.e(TAG, url);


        StringRequest req = new StringRequest(Request.Method.GET, url,

                new Listener<String>() {

                    @Override

                    public void onResponse(String text) {

                        LogUtils.i(TAG, text);

                        if (callback != null) {

                            LightResponse res = new LightResponse();

                            res.tag = tag;

                            res.url = url;

                            res.status = Models.StatusCode.NetworkSuccess;

                            res.setData(text);

                            callback.onFinish(res);

                        }

                    }

                }, new Response.ErrorListener() {

            @Override

            public void onErrorResponse(VolleyError error) {

                if (callback != null) {

                    LightResponse res = new LightResponse();

                    res.tag = tag;

                    res.url = url;

                    res.status = Models.StatusCode.NetworkError;

                    res.message = error.getMessage();

                    callback.onFinish(res);

                }

            }

        }) {

            @Override

            public Map<String, String> getHeaders() throws AuthFailureError {

                /* 此处是相对于实际业务配置的 */

                return new HashMap<String, String>();

            }

        };

        mQueue.add(req);

    }
说明:Volley有2种回调一种是onResponse,一种是onErrorResponse,但是实际开发中可能需要更多的回调需要处理,例如:
1 请求服务器成功,数据无误
2 请求服务器成功,但是可能返回的JSON数据有问题
3 服务器请求成功,但是返回码有问题
4 无网络连接
5 网络正常,但是服务器没返给我们数据(刷新失败)
6 系统发生异常
......
当然我们可以根据实际业务需求来设定相应的回调。
上面我只做了一个CallBack来回调,不管请求失败还是成功,我都调用了onFinish()方法
 4 回调处理
try {
            request.get(url, params, "", new CallbackLightRequest<LightResponse>() {
                @Override
                public void call(LightResponse response) {
                    if (response.isReplied()) {
                        ApiBeans.Followers2 bean = GsonUtil.getFromStr(ApiBeans.Followers2.class, response.getText());//json解析
                        if (bean != null && bean.data != null) {
                            httpCallback.onResponse(bean.data);//请求成功
                        } else {
                            httpCallback.onFailure(new RequestFailure(RequestFailure.Type.parse), null);//解析异常
                        }
                    } else {
                        httpCallback.onFailure(new RequestFailure(RequestFailure.Type.network), null);//网络异常
                    }
                }
            });
        } catch (Exception ex) {
   
            httpCallback.onFailure(new RequestFailure(RequestFailure.Type.exception), ex);//异常处理
        }
这里我做了2种类型的回调:
 一  成功
 二  失败(包含4种类型)
回调的接口如下:
public interface HttpCallback<T> {
    void onResponse(T response);//成功回调
    void onFailure(RequestFailure failure, Exception ex);//异常处理
}
 错误的回调类型,这里当然也可以封装成一个泛型
public class RequestFailure {
    public enum Type {
        network,//网络问题
        responseCode,//错误的返回码处理
        exception,//系统异常
        parse, //解析
    }
    public RequestFailure(Type type) {
        this.what = type;
    }
    public Type what;
}
 
network:代表网络连接异常
responseCode:错误的响应码处理
exception:系统异常处理
parse :Json解析异常
5 再次封装
    当上面的代码写多了之后,你会发现你一直在写重复的代码,仔细看看除了回调的对象不一样之外,其它都参数都基本一样,很容易就想到用泛型来对上面的代码进行封装,代码如下:
public static void getFolowFansList(final Context context, final LightRequest request, String userId, String profileUserId,
                                        String timeSince, int count, final HttpCallback<ApiBeans.FollowerListObject<Fan>> httpCallback) {
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("user_id", userId);
        params.put("count", count + "");
        params.put("since_time", timeSince);
        params.put("profile_user_id", profileUserId);
        String url = HttpConstant.DOMAIN_NORMAL + HttpConstant.FRIENDS_FANS_1;
      
        doRequest(request,url, data, httpCallback, ApiBeans.FollowerListObject.class);
    }
  把回调的代码用泛型进行封装
private static <T> void doRequest(LightRequest request,
                                      String url, HashMap<String, String> params,
                                      final HttpCallback callback, final Class<?> cls) {
        try {
            request.get(url, params, "", new CallbackLightRequest<LightResponse>() {
                @Override
                public void call(LightResponse response) {
                    if (response.isReplied()) {
                        T bean = GsonUtil.getFromStr(cls, response.getText());
                        if (bean != null) {
                            callback.onResponse(bean);
                        } else {
                            callback.onFailure(new RequestFailure(RequestFailure.Type.parse), null);
                        }
                    } else {
                        callback.onFailure(new RequestFailure(RequestFailure.Type.network), null);
                    }
                }
            });
        } catch (Exception ex) {
            callback.onFailure(new RequestFailure(RequestFailure.Type.exception), null);
        }
    }
 
6 volley 在项目中进行业务处理
下面看看如何现在封装的Volley在项目中进行业务处理的?
model.getFasList(mContext, lightRequest, Global.userDetail.userId, profileUserId, thisTimeSince, count,
                new HttpCallback<ApiBeans.FollowerListObject<Fan>>() {
              
                    @Override
                    public void onResponse(ApiBeans.FollowerListObject<Fan> data) {
                        try {
                             //数据返回成功
                            if (data.userList != null) {
                                adapter.setIsAllLoaded(data.infoCount < Constant.FEED_DEFAULT_NUM);
                                lv.setIfHasMore(data.infoCount, Constant.FEED_DEFAULT_NUM);
                                if (isRefresh) {
                                    adapter.setDataList(data.userList);
                                    lv.setAdapter(adapter);
                                } else {
                                    adapter.addDataList(data.userList);
                                    adapter.notifyDataSetChanged();
                                }
                            } else {
                            //刷新失败
                                if (isRefresh) {
                                    ToastModel.showRefreshFail(mContext);
                                } else {
                                    ToastModel.showLoadMoreError(mContext);
                                }
                            }
                        } catch (Exception e) {
                        } finally {
                            isDownloading = false;
                            if (loadingView != null) {
                                loadingView.setVisibility(View.GONE);
                                loadingView = null;
                            }
                            refreshEnd();
                        }
                    }
                    @Override
                    public void onFailure(RequestFailure failure, Exception ex) {
                          //网络异常
                        if (failure.what == RequestFailure.Type.network) {
                            ToastModel.showRed(mContext, R.string.tip_network_error);
                        } else if (failure.what == RequestFailure.Type.parse) {
                            //解析失败
                            ToastModel.showRed(mContext, "解析失败");
                        } else if (failure.what == RequestFailure.Type.exception) {
                            //系统异常
                            ToastModel.showRed(mContext, "系统异常");
                        }
                    }
                });
    }
 
   代码方便简单,通熟易懂,层次分明,逻辑清晰有没有呢?Volley不仅简化了我们的开发流程,而且可以让我们更专注于我们的业务处理。这是volley非常大的一个优点。
 
 

相关推荐