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自带的牛逼的初始化方法来解析响应
Q2 cookie
好不容易,把网络请求跑通了.
才发现,一个劲的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也是一套,
顶层完全不用去关注,底层的网络是如何实现的.(好像段老师
还是郝老师
这么说过)