android 网络请求框架总结(一)

网上有很多封装的很好用的网络请求框架如国内开源的Afinal,Xutils,JKFramework,都是良心之作,github上都有源码,还有网络上比较流行的AsyncHttpClient,OkHttp,Volley,Retrofit,Ion等等,我选择了Volley作为我项目的请求框架,原因有如下:
1、Volley是Google官方提供的,它的设计就是为Android网络交互而生的,非常适合数据量小而网络操作频繁的请求操作
2、Volley具有极强的可扩展性,底层数据传输可用Okhttp代替,Okhttp的传输速度更快

为了更利于项目的扩展和维护,我并没有直接拿来用,而是先进行了一层封装操作,Volley有一个很明显的优势,就是采用了队列的形式请求,一个简单的请求

 RequestQueue queue = Volley.newRequestQueue(this);

        StringRequest stringRequest = new StringRequest(Request.Method.GET, "url", new Response.Listener() {
            @Override
            public void onResponse(String response) {
                System.out.println("response = " + response);

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });

        queue.add(stringRequest);

创建一个请求队列,新建一个请求,将请求丢入请求队列,其他的事情就不用管了,等返回response结果就行了,很简单。

但实际项目中我不会每次请求都会创建一个RequestQueue,这样很浪费资源,也不符合Volley的设计理念,相当于我们要创建无数个队列(如果这样做还不如不用Volley),我们要保持Application的生命周期中只存在一个队列,我会创建一个请求的管理类来管理所有的请求,设计大概是这样的

public class HttpClient {
    public static RequestQueue queue = Volley.newRequestQueue(App.getContext());

    public static void postRequest(String url) {
        StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener() {
            @Override
            public void onResponse(String response) {
                System.out.println("response = " + response);

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });

        queue.add(request);
    }
}

所有的请求都用HttpClient调用requestPost方法就可以保持整个App的生命周期就只有一个请求队列了,虽然解决了第一步,还是有很多要做的,我要得到response的数据或者错误信息,要怎么做呢?使用接口回调,下面看一下,简单的接口实现

public interface OnResponseListener {
    void success(String response);

    void failure(String errorMessage);
}

HttpClient代码改为

public class HttpClient {
    public static RequestQueue queue = Volley.newRequestQueue(App.getContext());

    public static void postRequest(String url, final OnResponseListener listener) {
        StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener() {
            @Override
            public void onResponse(String response) {
                listener.success(response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                listener.failure(error.getLocalizedMessage());
            }
        });

        queue.add(request);
    }
}

使用

   HttpClient.postRequest("http://www.baidu.com", new OnResponseListener() {
            @Override
            public void success(String response) {
                System.out.println("response = " + response);
            }

            @Override
            public void failure(String errorMessage) {
                System.out.println("errorMessage = " + errorMessage);
            }
        });

只是改头换面,没有太大的改变,继续往下分析,我们还有那些事要处理,数据得到了,网络的交互用的大都是用json数据,我们需要对json数据进行解析,一般都是用对象去接收,要开始下一版的代码了

public class HttpClient {
    public static RequestQueue queue = Volley.newRequestQueue(App.getContext());

    public static final String RESULT_CODE = "code"; //状态码,后台返回成功或者失败
    public static final String RETURN_MESSAGE = "message";//消息,后台返回的文本消息,提示或者错误信息
    public static final String RESULT = "result";//成功的返回结果
    public static final String SUCCESS = "1"; //成功
    public static final String FAILURE = "0";//失败

    public static void postRequest(String url, final OnResponseListener listener) {
        StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject jsonObject = new JSONObject(response);//将json数据转化为json对象
                    if (!jsonObject.isNull(RESULT_CODE)) {//判断code字段是否存在
                        String code = jsonObject.getString(RESULT_CODE);//活得code的值
                        if (code.equals(SUCCESS)){ //成功则继续往下判断
                            if (!jsonObject.isNull(RESULT)){
                                String result = jsonObject.getString(RESULT);
                                listener.success(result);
                            }

                        }else if (code.equals(FAILURE)){//失败返回错误信息
                            if (!jsonObject.isNull(RETURN_MESSAGE)) {//判断message字段是否存在
                                listener.failure(jsonObject.getString(RETURN_MESSAGE));//返回后台失败信息
                            }

                        }else {
                            listener.failure("无效的状态码");//返回状态码无效的错误信息
                        }

                    }else {
                        listener.failure("状态码不存在");//返回状态码不存在的错误信息
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    listener.failure(e.getLocalizedMessage());//返回json异常的错误信息
                }
                listener.success(response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                listener.failure(error.getLocalizedMessage());//返回Volley异常的错误信息
            }
        });

        queue.add(request);//将请求添加到队列
    }
}

到这里,已经将返回的结果进行了处理,而且做了一个错误收集的工作,在failure可以直观的看到任何错误信息,对我们接口调试,应该是很有帮助的,当然你可能会问上面那些字段怎么来的,这些工作需要与后台协商约定,你也可以不叫这些名字,这些都无所谓,下面继续走,看看这段程序还缺什么,既然是请求,当然还需要有请求参数,还有返回的result还是json数据,使用的时候还需要进行手动解析,如下:

 public class HttpClient {
    public static RequestQueue queue = Volley.newRequestQueue(App.getContext());

    public static final String RESULT_CODE = "code"; //状态码,后台返回成功或者失败
    public static final String RETURN_MESSAGE = "message";//消息,后台返回的文本消息,提示或者错误信息
    public static final String RESULT = "result";//成功的返回结果
    public static final String SUCCESS = "1"; //成功
    public static final String FAILURE = "0";//失败

    public static void postRequest(String url, final Map map, final OnResponseListener listener) {
        StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject jsonObject = new JSONObject(response);//将json数据转化为json对象
                    if (!jsonObject.isNull(RESULT_CODE)) {//判断code字段是否存在
                        String code = jsonObject.getString(RESULT_CODE);//活得code的值
                        if (code.equals(SUCCESS)){ //成功则继续往下判断
                            if (!jsonObject.isNull(RESULT)){
                                String result = jsonObject.getString(RESULT);
                                listener.success(result);
                            }

                        }else if (code.equals(FAILURE)){//失败返回错误信息
                            if (!jsonObject.isNull(RETURN_MESSAGE)) {//判断message字段是否存在
                                listener.failure(jsonObject.getString(RETURN_MESSAGE));//返回后台失败信息
                            }

                        }else {
                            listener.failure("无效的状态码");//返回状态码无效的错误信息
                        }

                    }else {
                        listener.failure("状态码不存在");//返回状态码不存在的错误信息
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    listener.failure(e.getLocalizedMessage());//返回json异常的错误信息
                }
                listener.success(response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                listener.failure(error.getLocalizedMessage());//返回Volley异常的错误信息
            }
        }){
            @Override
            protected Map getParams() throws AuthFailureError {
                return map;
            }
        };

        queue.add(request);//将请求添加到队列
    }

使用

 Map<String,String> map = new HashMap<>();
        map.put("key1","value1");
        map.put("key2","value1");
        ...

        HttpClient.postRequest("http://www.baidu.com",map, new OnResponseListener() {
            @Override
            public void success(String result) {
                System.out.println("result = " + result);
                //这里我新建了一个测试的对象,采用了gson来将json数据转换为bean对象
                //解析成对象,嵌套的对象也是可以的
                TestBean testBean = new Gson().fromJson(result, TestBean.class);
                //解析成list
                Type type = new TypeToken<ArrayList<TestBean>>() {
                }.getType();
                List<TestBean> testBeans = new Gson().fromJson(result, type);
                //解析成数组
                TestBean[] testBeans1 = new Gson().fromJson(result, TestBean[].class);
                //这个时候想转化为list可以调用下面的方法
                List testBeans2 = Arrays.asList(testBeans1);

            }

            @Override
            public void failure(String errorMessage) {
                System.out.println("errorMessage = " + errorMessage);
            }
        });

到这里,我们已经可以得到数据,其他的工作就和他没什么关系了,再来检查一下我们还可以做那些事,一般在请求之前都需要检查网络状态的,可以这样做

  //判断网络是否连接
        if (NetworkUtils.isConnectedByState(App.getContext())) {
            queue.add(request);//将请求添加到队列
        }else {
            listener.failure("网络未连接");//返回网络未连接的错误信息
        }

基本的框架算是出来了,不过还有一些细节的优化,下一篇继续讲解

你可能感兴趣的:(android开发)