Volley使用技巧-----更好的封装(cookie的使用)
来源:互联网 发布:程序员的思维修炼 pdf 编辑:程序博客网 时间:2024/05/16 11:03
Volley使用技巧—–更好的封装(cookie的使用)
题外话
上一篇讲到如何自定义Request以便更方便的使用Volley,这篇即将分享的是如何更好用进行封装,使volley使用起来更加的方便,简单,顺便带上了关于cookie的处理方法.
正题
回顾上一篇博客中提到使用volley最初步骤,即创建一个请求队列:
mQueue = new Volley.RequestQueue(getApplicationContext());
这样的话每到一个activity或者fragment中,就不得不去重新创建一个队列,每个队列的生命周期也跟随着activity或者fragment,为了避免这种繁琐的情况,可以自定义一个工具类,其中持有一个队列,这个队列的生命周期跟随整个应用.
搜寻了一下,发现android应用在创建的时候会有一个application类实例跟随着产生,如果对Application类不是很熟悉的话,可以参考这篇博客.下面是自定义出来的application类:
public class RequestQueueController extends Application{ //关于cookie的关键字 private static final String SET_COOKIE_KEY = "Set-Cookie"; private static final String COOKIE_KEY = "Cookie"; private static final String COOKIE_USERNAME = "username"; //请求队列 private RequestQueue _requestQuene; //SharedPreferences,用于存储少量的数据 private SharedPreferences _preferences; //本类的实例 private static RequestQueueController _instance; public static RequestQueueController get() { return _instance; } /** * 该方法在应用运行的时候就会自动调用 */ @Override public void onCreate() { super.onCreate(); _instance = this; _preferences = getSharedPreferences(AppConstant.PREFERENCE_NAME,0); _requestQuene = Volley.newRequestQueue(this); } /** * 返回请求队列 * @return */ public RequestQueue getRequestQueue() { return _requestQuene; } /** * 用于检测返回头中包含的cookie * 并且更新本地存储的cookie * @param headers */ public final void checkSessionCookie(Map<String, String> headers) { if (headers.containsKey(SET_COOKIE_KEY)) { String cookie = headers.get(SET_COOKIE_KEY); if((cookie.length()) > 0 && (!cookie.contains("saeut"))) { String[] splitCookie = cookie.split(";"); String[] splitSessionId = splitCookie[0].split("="); cookie = splitSessionId[1]; SharedPreferences.Editor prefEditor = _preferences.edit(); prefEditor.putString(COOKIE_USERNAME, cookie); prefEditor.apply(); } } } /** * 向请求头中加入cookie * @param headers */ public final void addSessionCookie(Map<String, String> headers) { String sessionId = _preferences.getString(COOKIE_USERNAME, ""); if (sessionId.length() > 0) { StringBuilder builder = new StringBuilder(); builder.append(COOKIE_USERNAME); builder.append("="); builder.append(sessionId); if (headers.containsKey(COOKIE_KEY)) { builder.append("; "); builder.append(headers.get(COOKIE_KEY)); } headers.put(COOKIE_KEY, builder.toString()); } }}
上面的自定义类继承了Application类,记住还需要在AndroidManifest.xml中的Application标签中加入RequestQueueController
(自定义类名),将这个自定义类和Application绑定到一起,就可以在应用启动的时候执行onCreate()方法中的代码了;
处理好了请求队列的创建之后,再来分析request,之前使用request都是直接创建两个listener来处理,写在一起会让代码看上去冗余,就类似这样:
request.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //处理请求成功返回的结果 Response.Listener<String> listener = new Response.Listener<String>() { @Override public void onResponse(String s) { Log.e("dada", s); } }; //处理请求错误返回的结果 Response.ErrorListener errorListener = new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { Log.e("error", volleyError.toString()); } }; //实例化请求对象 StringRequest stringRequest = new StringRequest("http://www.baidu.com", listener, errorListener); //向队列中加入请求 requestQueue.add(stringRequest); requestQueue.start(); } });
可以模仿Angularjs那种模式来将这些分层,大致分为三层:
- 最底层的API,负责创建Request并加入请求队列,根据返回值的需求不同来封装.供第二层来调用.
- 将最顶层传入的信息传给最底层的API,并将请求返回的信息处理(根据自己的情况来处理),通过回调接口传递给顶层的调用者.
- 顶层的调用者只需要给出相应的第二层调用和相关参数,其余可以不用管理.
经过上面三层的分离之后,每一层都有明确的分工,而且互不干扰,更方便开发者调用,下面给出上面三层的代码(封装了JSONArrayRequestPlus的API,其余的是相同的道理):
/** * 最底层的API * 只根据传来的参数创建了Request * 并将其加入了队列中 */public class HttpApi { /** * 返回JsonArray的网络请求Api * @param method * @param url * @param requestBody * @param listener * @param errorListener */ public static void DoJsonArrayRequest(int method, String url, HashMap hashMap, Response.Listener<JSONArray> listener, Response.ErrorListener errorListener) { final HashMap<String,String> map = hashMap; try{ JsonArrayRequestPlus jsonArrayRequestPlus = new JsonArrayRequestPlus(method, url, listener, errorListener){ @Override protected Map<String, String> getParams() throws AuthFailureError { return map; } }; RequestQueueController.get().getRequestQueue().add(jsonArrayRequestPlus); } catch (Exception e) { e.printStackTrace(); } }}
最底层的API弄好之后,第二层就对其直接调用,也就是第三层调第二层,第二层调第一层,返回结果给第二层做处理,再回传需要的结果给顶层的调用者.
/** * 第二层相当与传输层 * 也负责了对数据进行处理 */public class HttpService { /** * 登录请求 *///自持有一个接口,这个接口就是用来传递结果的,接口的定义就在下面一行,两个函数分别对应着Volley给出的两个接口 private static OnLoginRequestResponseListener mLoginRequestListener; public static interface OnLoginRequestResponseListener { public void OnLoginSuccessResponse(JSONArray jsonArray); public void OnLoginErrorResponse(String errorResult); } public static void DoLoginRequest (int method, String url, HashMap<String,String> hashMap, OnLoginRequestResponseListener listener ) { mLoginRequestListener = listener; Response.Listener<JSONArray> responseListener = new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray jsonArray) { mLoginRequestListener.OnLoginSuccessResponse(jsonArray); } }; Response.ErrorListener errorListener = new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { mLoginRequestListener.OnLoginErrorResponse(volleyError.getMessage()); } }; HttpApi.DoJsonArrayRequest(method, url, hashMap, responseListener, errorListener); } /** * 注册请求 *///这个类似于上面的,调用的是同一个底层的接口,一次封装多次调用,很方便 private static OnSignupRequestResponseListener mSignupRequestListener; public static interface OnSignupRequestResponseListener { public void OnSignupSuccessResponse(JSONArray jsonArray); public void OnSignupErrorResponse(String errorResult); } public static void DoSignupRequest (int method, String url, HashMap<String, String> hashMap, OnSignupRequestResponseListener listener ) { mSignupRequestListener = listener; Response.Listener<JSONArray> responseListener = new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray jsonArray) { mSignupRequestListener.OnSignupSuccessResponse(jsonArray); } }; Response.ErrorListener errorListener = new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { mSignupRequestListener.OnSignupErrorResponse(volleyError.getMessage()); } }; HttpApi.DoJsonArrayRequest(method, url, hashMap, responseListener, errorListener); }}
第二层弄完了之后,第三层就剩下实现回调接口以及调用了,实现的代码如下:
public class MainActivity extends ActionBarActivity implements HttpService.OnLoginRequestResponseListener{ //提交请求的按钮 private Button request; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); request.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { HttpService.DoLoginRequest(Request.Method.POST,url,map,MainActivity.this); } }); }//后面这两个重写的方法就是第二层中需要调用的回调方法,在这里接收到信息后做出响应,这里没有给出具体的处理代码 @Override public void OnLoginSuccessResponse(JSONArray jsonArray) { } @Override public void OnLoginErrorResponse(String errorResult) { }}
关于cookie
在开头的自定义Application类中已经定义了两个方法,就是存取cookie值的方法,只需要在自定义的request中加入这两个方法就可以了,相关加入位置如下:
public class JsonArrayRequestPlus extends Request<JSONArray>{ private final Response.Listener<JSONArray> mListener; public JsonArrayRequestPlus(int method, String url, Response.Listener<JSONArray> listener, Response.ErrorListener errorListener) { super(method, url, errorListener); mListener = listener; }//重写getHeader()方法,请求会自动调用这个方法来获取请求头部,所以我们将本地的cookie存放进一个map返回回去,cookie就会包含到header里面去 @Override public Map<String, String> getHeaders() throws AuthFailureError { Map<String, String> headers = super.getHeaders(); if(headers == null || headers.equals(Collections.emptyMap())) { headers = new HashMap<>(); }//这个方法就是自定义Application类中添加cookie的方法RequestQueueController.get().addSessionCookie(headers); return headers; } @Override protected void deliverResponse(JSONArray jsonArray) { mListener.onResponse(jsonArray); } @Override protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {//在处理返回信息的时候,服务器会返回cookie,在这里截取到cookie并且存储到本地RequestQueueController.get().checkSessionCookie(response.headers); try { String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); return Response.success(new JSONArray(jsonString), HttpHeaderParser.parseCacheHeaders(response)); } catch (UnsupportedEncodingException e) { return Response.error(new ParseError(e)); } catch (JSONException je) { return Response.error(new ParseError(je)); } }}
关于这些如果还有什么不明白的,可以直接给小达留言,或者直接加QQ2319821734,希望能和大家相互学习交流,共同进步~今天就到这里咯,晚安~
- Volley使用技巧-----更好的封装(cookie的使用)
- volley的封装使用
- Cookie的使用(含cookie的封装)
- 使用CRTP做更好的封装
- 使用CRTP做更好的封装
- cookie的JS封装使用
- cookie的封装与使用
- Volley网络请求的简单封装使用
- Volley的使用(三) 简单封装
- Android:网络层的封装(使用volley)
- Volley的使用(三):Volley与Activity的联动 + Volley的二次封装
- 对Volley框架进行封装,以便于更好地使用Volley。
- 使用JavaScript 对Cookie 操作的封装
- 自己对volley http模块的二次封装的使用
- Android:Volley的使用及其工具类的封装
- Volley的使用及其工具类的封装
- Android:Volley的使用及其工具类的封装
- 使用Volley框架网络请求Request<T>的封装
- poj3070
- HDOJ 题目3364 Lanterns(高斯消元,开关灯问题)
- KMP算法
- wehkskjv32532432
- Computer Network L1 概论
- Volley使用技巧-----更好的封装(cookie的使用)
- 多线程下载及原理
- HDOJ 题目3364 Lanterns(高斯消元,开关灯问题)
- jfkghksgkdsnvui345893957hskjdsrh7345whsdy345ihk
- Linux学习笔记(系统日常管理-2)
- Could not source '/Users/Chufengze/.rvm/scripts/scripts/base' as file does not exist.
- 图像处理SCI论文常用表述收集,持续更新
- jnnxckk845ifs yf6qwrsd
- Netty为啥可靠(一)