初用Volley

Context

水壶架iOS端终于撸完了

由于我Android的界面写的烂的一逼,所以只能拜托xiaopo来帮我撸界面了.

首要目标是干掉蓝牙类,不过蓝牙绑定设备的时候会需要网络请求.

那就顺便把网络也给撸掉吧~

基本用法

1.需要一个请求队列

RequestQueue mQueue = Volley.newRequestQueue(context);

2.好了直接撸请求吧

Form-Data这么搞

StringRequest stringRequest = new StringRequest("一个URL",new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
               Log.d("Network OK", response);
        }
        }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
               Log.e("Network Fail", error.getMessage(), error);
        }
});

JSON这么搞

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("http://m.weather.com.cn/data/101010100.html", null,
    new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            Log.d("Network OK", response.toString());
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.e("Network Fail", error.getMessage(), error);
        }
    });

Q1 请求是form-data 响应是json

不过这里遇到了一个问题.

我们服务器大佬坑我,请求只能解析Form-Data的,返回的响应是Json

于是只能手动转换了

private static StringRequest FormDataRequest(String url, int method, Map parameter, VKNetworkSucceedBlock succeedBlock, VKNetworkFailBlock failBlock) {
    StringRequest request=new StringRequest(method, url, new Response.Listener<String>() {

        @Override
        public void onResponse(String response) {
            try {
                JSONObject jsonResponse = new JSONObject(response);
                if (jsonResponse.getInt("status") == 10086) {
                    //认证失败
                    failBlock.requestFail(new Exception("SessionExpired"));
                } else {
                    succeedBlock.getResponse(jsonResponse);
                }
            } catch (JSONException e) {
                e.printStackTrace();
                failBlock.requestFail(e);
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            if (error.networkResponse.statusCode == 10000) {
                //认证失败
                failBlock.requestFail(new Exception("SessionExpired"));
            } else
                failBlock.requestFail(error);
        }}){
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            return parameter;
        }
    };
    queue().add(request);
    return request;
}

用JSONObject自带的牛逼的初始化方法来解析响应

好不容易,把网络请求跑通了.

才发现,一个劲的403.

原来,Volley本身不处理Cookie的!!

啊席巴

于是就要手动处理

private static StringRequest FormDataRequest(String url, int method, Map parameter, VKNetworkSucceedBlock succeedBlock, VKNetworkFailBlock failBlock) {
    StringRequest request=new StringRequest(method, url, new Response.Listener<String>() {

        @Override
        public void onResponse(String response) {
           //这些你都看过了
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            //这些你都看过了
            }){
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            return parameter;
        }

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String,String> header=super.getHeaders();
            String cookie=getCookie();
            if (cookie!=null){
                header.put("Set-Cookie",cookie);
                //手动从把Cookie放到Header中
            }
            return header;
        }

        @Override
        protected Response<String> parseNetworkResponse(NetworkResponse response) {
            refreshCookie(response.headers);
                //手动从Response的Header中获取Cookie
            return super.parseNetworkResponse(response);
        }
    };
    queue().add(request);
    return request;
}

这其中的Cookie持久化什么的,就不说了.它不是重点.

而重点是……

Final 我放弃了

当Response的Header中有多个Set-Cookie字段时,只会被解析出来一个!

如果需要把所有的Cookie都拿出来的话,需要修改Volley源码!

然而,我使用Gradle来添加Volley工程的,所以,你逗我吗!

于是乎,我就放弃了.

姜还是老的辣

大三的时候做精益防伪,使用了Android-Async-Http

这个很牛逼,功能很强大,还自动缓存了Cookie,真是替我省心.

还好前面撸接口的时候,封装的比较好,所以没有改动太多的东西.

Tip

封装了两个基本网络操作函数

public static void getMethodFormData(String url, Map<String,String> parameter, VKNetworkSucceedBlock succeedBlock, VKNetworkFailBlock failBlock){
    getViaLoopj(url,parameter,succeedBlock,failBlock);
}

public static void postMethodFormData(String url, Map<String,String> parameter, VKNetworkSucceedBlock succeedBlock, VKNetworkFailBlock failBlock){
    postViaLoopj(url,parameter,succeedBlock,failBlock);
}

再来一发Android-Async-Http的实例(封装过了)

public static void postViaLoopj(String url, Map<String,String> params,VKNetworkSucceedBlock succeedBlock,VKNetworkFailBlock failBlock) {
    client.post(url, new RequestParams(params), new JsonHttpResponseHandler(){
        @Override
        public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
            if (statusCode==403){
                failBlock.requestFail(new Exception("SessionExpired"));
            }else
            {
                succeedBlock.getResponse(response);
            }
        }
        @Override
        public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
            super.onFailure(statusCode, headers, throwable, errorResponse);
            if (statusCode==403){
                failBlock.requestFail(new Exception("SessionExpired"));
            }else{
                failBlock.requestFail(new Exception(errorResponse.toString()));
            }
        }
        @Override
        public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
            super.onFailure(statusCode, headers, responseString, throwable);
            if (statusCode==403){
                failBlock.requestFail(new Exception("SessionExpired"));
            }else
                failBlock.requestFail(new Exception(responseString));
        }
    });
}

定义了两个interface

public interface VKNetworkSucceedBlock {
    void getResponse(JSONObject responseObject);
}

public interface VKNetworkFailBlock {
    void requestFail(Exception error);
}

于是乎做网络请求,就方便的很了

public static void mLogin(String email, String verify, boolean isChina, NetworkUtils.VKNetworkSucceedBlock succeed, NetworkUtils.VKNetworkFailBlock fail){
    HashMap<String,String> map=new HashMap<String, String>(){{
            put("hhh","123@163.com");
            put("jjj","3434");
            put("kkk",String.valueOf(1));
        }};
      NetworkUtils.postMethodFormData(UrlManager.URL_Login,map,succeed,fail);
}

最后网络的效果,就留到具体调用他的类去实现吧.

所以,封装了一遍就是好瞧把你能耐的,更换网络框架,不需要跑到每个Activity啊,Class里面去改.

response也是一套,

顶层完全不用去关注,底层的网络是如何实现的.(好像段老师还是郝老师这么说过)

当然我相信,来看这篇文章的大佬们,肯定早就知道这个了