国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android 中Volley二次封裝并實現網絡請求緩存

2019-10-22 18:28:24
字體:
來源:轉載
供稿:網友

Android 中Volley二次封裝并實現網絡請求緩存

Android目前很多同學使用Volley請求網絡數據,但是Volley沒有對請求過得數據進行緩存,因此需要我們自己手動緩存。 一下就是我的一種思路,僅供參考

具體使用方法為:

HashMap<String,String> params = new HashMap<>();params.put("id", "1");params.put("user", "mcoy");new NetWorkHelper(getActivity()).jacksonMethodRequest("method_id", params, new TypeReference<ReturnTemple<FirstCategories>>(){}, handler, msgId);

NetWorkHelper---對Volley的封裝,首先調用CacheManager.get(methodName, params);方法獲取緩存中的數據,如果數據為null,

則繼續發送網絡請求。

/**  * @version V1.0 網絡請求幫助類  * @author: mcoy  */ public final class NetWorkHelper {    private NetWorkManager netWorkUtils;    public NetWorkHelper(Context context){     netWorkUtils = new NetWorkManager(context);   }    public static final String COMMON_ERROR_MSG = "連接超時,請稍后重試";   public static final int COMMON_ERROR_CODE = 2;     /**    * 使用Jackson請求的方法    * @param methodName    * @param params    * @param handler    * @param msgId    */   public void jacksonMethodRequest(final String methodName,final HashMap<String,String> params,TypeReference javaType, final Handler handler,final int msgId){      ResponseListener listener =  new ResponseListener(){       @Override       public void onResponse(Object response, boolean isCache) {         PrintLog.log(response.toString());         if (isCache){           CacheManager.put(methodName, params, response);         }         if (handler != null) {           Message message = handler.obtainMessage();           message.what = msgId;           message.obj = response;           handler.sendMessage(message);         }       }     };      Object respone = CacheManager.get(methodName, params);     if(respone != null){       listener.onResponse(respone,false);       return;     }      HashMap<String,String> allParams = Config.setSign(true);     allParams.putAll(params);     Response.ErrorListener errorListener = new Response.ErrorListener() {       @Override       public void onErrorResponse(VolleyError error) {         error.printStackTrace();         if (handler != null) {           Message message = handler.obtainMessage();           message.what = msgId;           message.obj = COMMON_ERROR_MSG;           handler.sendMessage(message);         }       }     };     netWorkUtils.jacksonRequest(getUrl(methodName), allParams,javaType, listener, errorListener);   }    /**    * Url直接請求    * @param url    * @param params    * @param handler    * @param msgId    */   public void urlRequest(String url,HashMap<String,String> params,JsonParser jsonParser,final Handler handler,final int msgId){      request(url, true, params, jsonParser, handler, msgId);   }    /**    * 通過方法請求    * @param methodName 方法名    * @param params 請求參數    * @param jsonParser Json解析器    * @param handler 回調通知    * @param msgId 通知的Id    */   public void methodRequest(String methodName, final HashMap<String,String> params,final JsonParser jsonParser,final Handler handler,final int msgId){     request(getUrl(methodName),true,params,jsonParser,handler,msgId);   }    /**    * 通過方法請求    * @param methodName 方法名    * @param params 請求參數    * @param jsonParser Json解析器    * @param handler 回調通知    * @param msgId 通知的Id    */   public void methodRequest(String methodName, boolean isLogin,final HashMap<String,String> params,final JsonParser jsonParser,final Handler handler,final int msgId){     request(getUrl(methodName),isLogin,params,jsonParser,handler,msgId);   }       private void request(final String url, boolean isLogin,final HashMap<String,String> params,final JsonParser jsonParser,final Handler handler,final int msgId){     final HashMap<String,String> allParams = Config.setSign(isLogin);     allParams.putAll(params);     Response.Listener listener = new Response.Listener<String>() {       @Override       public void onResponse(String response) {         /**          * 有些請求默認是沒有parser傳過來的,出參只求String,譬如聯合登錄等          * 所以加了一個else if          */         Object result;         PrintLog.log(response);         if (jsonParser != null ) {           jsonParser.json2Obj(response);           jsonParser.temple.description = jsonParser.temple.getResultDescription();           result = jsonParser.temple;         } else {           ReturnTemple temple = new ReturnTemple();           temple.issuccessful = false;           temple.description = COMMON_ERROR_MSG;           temple.result = -100;           result = temple;         }         if (handler != null) {           Message message = handler.obtainMessage();           message.what = msgId;           message.obj = result;           handler.sendMessage(message);         }       }     };      Response.ErrorListener errorListener = new Response.ErrorListener() {       @Override       public void onErrorResponse(VolleyError error) {         Object result;         if (jsonParser != null) {           ReturnTemple temple = new ReturnTemple();           temple.issuccessful = false;           temple.description = COMMON_ERROR_MSG;           temple.result = COMMON_ERROR_CODE;           result = temple;         } else {           result = COMMON_ERROR_MSG;         }         if (handler != null) {           Message message = handler.obtainMessage();           message.what = msgId;           message.obj = result;           handler.sendMessage(message);         }       }     };     netWorkUtils.request(url, allParams, listener, errorListener);   }    /**    * 根據訪求名拼裝請求的Url    * @param methodName    * @return    */   private String getUrl(String methodName){     String url = Config.getUrl();     if (!StringUtil.isNullOrEmpty(methodName)) {       url = url + "?method=" + methodName;     }     return url;   } } 

CacheManager---將針對某一method所請求的數據緩存到本地文件當中,主要是將CacheRule寫到本地文件當中

/**  * @version V1.0 <緩存管理>  * @author: mcoy  */ public final class CacheManager {   /**    * 一個方法對應的多個Key,比如分類都是同一個方法,但是請求會不一樣,可能都要緩存    */   private static HashMap<String, ArrayList<String>> methodKeys;   private static final String keyFileName = "keys.pro";    /**    * 讀取緩存的Key    */   public static void readCacheKey() {     methodKeys = (HashMap<String, ArrayList<String>>) readObject(keyFileName);     if (methodKeys == null) {       methodKeys = new HashMap<String, ArrayList<String>>();     }   }    /**    * 保存緩存    */   public static void put(String method, HashMap<String, String> params, Object object) {     long expireTime = CacheConfig.getExpireTime(method);     if (expireTime <= 0 || methodKeys == null) {//有效時間小于0,則不需要緩存       return;     }     String key = createKey(method, params);     if (methodKeys.containsKey(method)) {       ArrayList<String> keys = methodKeys.get(method);       keys.add(key);     } else {       ArrayList<String> keys = new ArrayList<>();       keys.add(key);       methodKeys.put(method, keys);     }     writeObject(methodKeys, keyFileName);     String fileName = key + ".pro";     CacheRule cacheRule = new CacheRule(expireTime, object);     LogModel.log(" put " + method + " " + key + " " + cacheRule);     writeObject(cacheRule, fileName);   }    public static Object get(String method, HashMap<String, String> params) {     long expireTime = CacheConfig.getExpireTime(method);     if (expireTime <= 0 || methodKeys == null || !methodKeys.containsKey(method)) {//有效時間小于0,則不需要緩存       return null;     }     ArrayList<String> keys = methodKeys.get(method); //    String saveKey = keys.get(method);     String key = createKey(method, params);     String fileName = key + ".pro"; //    LogModel.log("get"+method+" "+(saveKey.equals(key))+" path:"+fileName);      CacheRule cacheRule = null;     try {       if (keys.contains(key)) {         cacheRule = (CacheRule) readObject(fileName);       }     } catch (Exception e) {       e.printStackTrace();     }     LogModel.log("get :" + method + " " + key + " " + cacheRule);     if (cacheRule != null && cacheRule.isExpire()) {       return cacheRule.getData();     } else {       return null;     }   }     public static void main(String[] args) {     String method = "category.getCategory";     HashMap<String, String> params = new HashMap<>();     params.put("categoryId", "-3");     System.out.println(createKey(method, params));     System.out.println(CacheRule.getCurrentTime());   }    /**    * 生成Key    *    * @param method 請求的方法名    * @param params 私有參數(除公共參數以外的參數)    * @return    */   private static String createKey(String method, HashMap<String, String> params) {     try {       MessageDigest digest = MessageDigest.getInstance("md5");       digest.digest(method.getBytes("UTF-8"));       StringBuilder builder = new StringBuilder(method);       if (params != null && params.size() > 0) {         Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();         while (iterator.hasNext()) {           Map.Entry<String, String> entry = iterator.next();           builder.append(entry.getKey()).append("=").append(entry.getValue());         }       }       byte[] tempArray = digest.digest(builder.toString().getBytes("UTF-8"));       StringBuffer keys = new StringBuffer();       for (byte b : tempArray) {         // 與運算         int number = b & 0xff;// 加鹽         String str = Integer.toHexString(number);         // System.out.println(str);         if (str.length() == 1) {           keys.append("0");         }         keys.append(str);       }       return keys.toString().toUpperCase();     } catch (Exception e) {       e.printStackTrace();     }     return method.toUpperCase();   }    /**    * 將對象寫到文件中    *    * @param object    * @param fileName    */   private static void writeObject(Object object, String fileName) {     try {       ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(new File(CacheConfig.getCachePath() + fileName)));       oo.writeObject(object);       oo.close();     } catch (IOException e) {       e.printStackTrace();     }   }    /**    * 讀取對象    *    * @param fileName    * @return    */   private static Object readObject(String fileName) {     Object result = null;     try {       File file = new File(CacheConfig.getCachePath() + fileName);       if (file.exists()) {         ObjectInputStream oi = new ObjectInputStream(new FileInputStream(file));         result = oi.readObject();         oi.close();       }     } catch (Exception e) {       e.printStackTrace();     }     return result;   } } 

CacheConfig---初始化哪些方法需要做緩存處理,以及緩存的有效時間

/**  * @version V1.0 <設置哪些類數據需要緩存>   * @author: mcoy  */ public final class CacheConfig {   /**方法對應的緩存有效時間,時間是毫秒*/   private static HashMap<String,Long> methodExpireTimes = new HashMap<String, Long>();   private static String cachePath = null;    static {     methodExpireTimes.put(ConstMethod.GET_CATEGORY_LIST,30 * 60 * 1000L);     methodExpireTimes.put(ConstMethod.GET_NEW_CATEGORY_LIST,30 * 60 * 1000L);   }    /**    * 初始化緩存路徑    * @param context    */   public static void init(Context context){     cachePath = context.getFilesDir().getPath()+ File.separator+"cache"+File.separator;     File file = new File(cachePath);     if(!file.exists()){       file.mkdirs();     }     CacheManager.readCacheKey();   }    /**緩存路徑*/   public static String getCachePath() {     return cachePath;   }    /**    * 獲取有方法對應的有效時間,如果方法沒有添加緩存或者緩存時間小于0,則不添加緩存    * @param method    * @return    */   public static long getExpireTime(String method){     if(methodExpireTimes.containsKey(method)){       return methodExpireTimes.get(method);     }else {       return -1;     }   } } 

CacheRule---主要有兩個參數,expireTime需要緩存的時間, data需要緩存的數據

public class CacheRule implements Serializable{   /** 有效時間 */   public long expireTime;   /** 緩存時間*/   public long cacheTime;   /** 緩存數據 */   private Object data;    public CacheRule(long expireTime,Object data){     cacheTime = getCurrentTime();     this.expireTime = expireTime;     this.data = data;   }    public Object getData() {     return data;   }    public void setData(Object data) {     this.data = data;   }    @Override   public int hashCode() {     return BeanTools.createHashcode(expireTime, cacheTime, data);   }    @Override   public String toString() {     StringBuilder builder = new StringBuilder();     builder.append("expireTime:").append(expireTime).append(" cacheTime:").append(cacheTime)         .append(" curTime:").append(getCurrentTime())         .append(" isExpire:").append(isExpire()).append(" data:").append(data==null?"null":data.toString());     return builder.toString();   }    /**    * 數據是否有效    * @return    */   public boolean isExpire(){     long curTime = getCurrentTime();     return curTime>(expireTime+cacheTime)?false:true;   }    /**    * 獲取當前時間    * @return    */   public static long getCurrentTime(){ //    if (Build.VERSION_CODES.JELLY_BEAN_MR1 <= Build.VERSION.SDK_INT) { //      return SystemClock.elapsedRealtimeNanos(); //    } else {       return System.currentTimeMillis(); //    }   } } 

NetWorkManager---往RequestQueue中添加JacksonRequest請求,然后Volley會去請求數據

/**  * 網絡請求的工具類  */ public final class NetWorkManager {     private RequestQueue requestQueue ;    public NetWorkManager(Context context){     requestQueue = Volley.newRequestQueue(context);   }       /**    * 使用Jackson解析請求的方法    * @param url    * @param params    * @param javaType 成功時返回的Java類型    * @param listener    * @param errorListener    */   public void jacksonRequest(final String url,final HashMap<String,String> params,TypeReference javaType, ResponseListener listener, Response.ErrorListener errorListener){     JacksonRequest jacksonRequest = new JacksonRequest(url,javaType,params,listener,errorListener);     requestQueue.add(jacksonRequest);   }    /**    * 普通的網絡請求,返回的Json    * @param url    * @param params    * @param listener    * @param errorListener    */   public void request(final String url,final HashMap<String,String> params,Response.Listener listener,Response.ErrorListener errorListener){      StringRequest stringRequest = new StringRequest(Request.Method.POST,url,listener,errorListener){       @Override       protected Map<String, String> getParams() throws AuthFailureError {         if (PrintLog.DEBUG) {           Iterator<Map.Entry<String,String>> iterator = params.entrySet().iterator();           StringBuilder builder = new StringBuilder(url+" ");           while (iterator.hasNext()){             Map.Entry<String,String> entry = iterator.next();             builder.append(entry.getKey()+":"+entry.getValue()).append("; ");           }           PrintLog.log(builder.toString());         }         return params;       }     };     requestQueue.add(stringRequest);   }   } 

JacksonRequest---繼承Request,重寫deliverResponse方法,并調用ResponseListener的onResponse方法,并通過CacheManager.put(methodName, params, response);將獲取的response緩存到CacheManager中。這一步很重要,調用我們自己的listener,而不是Volley提供給我們的Response.Listener

/**  * Created by mcoy  */ public class JacksonRequest extends Request {   private final HashMap<String,String> params;   private final ResponseListener listener;   private final ObjectMapper mapper;   private final TypeReference javaType;    public JacksonRequest(String url,TypeReference javaType,HashMap<String,String> params,ResponseListener listener,Response.ErrorListener errorListener){     super(Method.POST,url,errorListener);     mapper = new ObjectMapper();     mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES,true);     mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);     this.params = params;     this.listener = listener;     this.javaType = javaType;   }    @Override   protected Map<String, String> getParams() throws AuthFailureError {     return params;   }    @Override   protected Response parseNetworkResponse(NetworkResponse response) {     String json;     try {       json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));       PrintLog.log("返回的json:" + json);       return Response.success(mapper.readValue(json,javaType), HttpHeaderParser.parseCacheHeaders(response));     }catch (UnsupportedEncodingException e){       json = new String(response.data);       PrintLog.log("json:"+json);       try {         return Response.success(mapper.readValue(json,javaType),HttpHeaderParser.parseCacheHeaders(response));       } catch (IOException e1) {         return Response.error(new ParseError(e));       }     } catch (JsonParseException e) {       PrintLog.log(e.toString());       return Response.error(new ParseError(e));     } catch (JsonMappingException e) {PrintLog.log(e.toString());       return Response.error(new ParseError(e));     } catch (IOException e) {PrintLog.log(e.toString());       return Response.error(new ParseError(e));     }   }    @Override   protected void deliverResponse(Object response) {     listener.onResponse(response,true);   }  } 

ResponseListener---自定義的一個listener接口, 在發送請求時,需要將其實現。其中才參數中比Volley的提供的listener過了一個isCache的Boolean值,根據此值來決定是否要緩存。

/**  * @version V1.0 <描述當前版本功能>  * @author: mcoy  */ public interface ResponseListener<T> {   public void onResponse(T response, boolean isCache); } 

如有疑問請留言或者到本站社區交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 诏安县| 长泰县| 绥中县| 阿拉善右旗| 芜湖市| 时尚| 莆田市| 敖汉旗| 铜陵市| 黄龙县| 南涧| 青海省| 龙游县| 饶平县| 明溪县| 庆城县| 康定县| 运城市| 平果县| 固安县| 新宁县| 河北省| 邵阳市| 肃宁县| 鸡泽县| 长武县| 双江| 宽甸| 顺义区| 嘉兴市| 枣庄市| 商城县| 大田县| 和静县| 武定县| 克什克腾旗| 且末县| 桂林市| 禹城市| 潮安县| 南昌县|