Android 中Volley二次封装并实现网络请求缓存

Android 中Volley二次封装并实现网络请求缓存,第1张

概述Android中Volley二次封装并实现网络请求缓存Android目前很多同学使用Volley请求网络数据,但是Volley没有对请求过得数据进行缓存,因此需要我们自己手动缓存。一下就是我的一种思路,仅供参考

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,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,JsonParser JsonParser,final int msgid){      request(url,true,JsonParser,msgid);   }    /**    * 通过方法请求    * @param methodname 方法名    * @param params 请求参数    * @param JsonParser Json解析器    * @param handler 回调通知    * @param msgid 通知的ID    */   public voID methodRequest(String methodname,final JsonParser JsonParser,final int msgid){     request(getUrl(methodname),boolean isLogin,isLogin,msgid);   }       private voID request(final String url,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,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,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,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,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,ResponseListener Listener,Response.ErrorListener errorListener){     JacksonRequest jacksonRequest = new JacksonRequest(url,errorListener);     requestQueue.add(jacksonRequest);   }    /**    * 普通的网络请求,返回的Json    * @param url    * @param params    * @param Listener    * @param errorListener    */   public voID request(final String url,Response.Listener Listener,Response.ErrorListener errorListener){      StringRequest stringRequest = new StringRequest(Request.Method.POST,url,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,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,Response.ErrorListener errorListener){     super(Method.POST,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,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 中Volley二次封装并实现网络请求缓存全部内容,希望文章能够帮你解决Android 中Volley二次封装并实现网络请求缓存所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1144559.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存