文章地址:http://blog.csdn.net/intbird
- 两个开源代码
- 实现想法
- 简单实现的一些简化做法
两个开源代码
也足够用了,没必要自己去写,文件很小
- reservoir 缓存对象为字符串;
- disklrucache 存取sd卡工具;
实现想法
也就是将接口的字符串缓存到本地而已;不一定是网络缓存,可以指定任何想要的字符串保存,如果愿意可以用数据库等等,看需要咯,减轻服务器加载压力
- 在保证接口正常调用的情况下嵌入缓存管理方式,不对之前的代码造成任何影响,且方便替换;
- 不同的接口可以自定义缓存的过期时间,这个时间可以是服务器接口的时间,也可以是本地定死的时间;
- 加载逻辑为每次先将该接口字段所有数据toString()后做一个MD5作为键,同时将写入时间和缓存时间保存下来;取出的时候根据当前时间和写入时间以及缓存时间去判断缓存是否可用;
由于很简单这个可用花点时间做的更好点,比如不同接口不同时间,完全使用缓存还是缓存过期后仍使用缓存,等待网络加载完成后重新写入等等看需要;
不同项目不同网络层,网络加载的使用之前写过一个,在这里:
http://blog.csdn.net/intbird/article/details/38338623
简单实现的一些简化做法
对于缓存的额外信息需要的不是很大,所以判断换存时间的方式不是Map
private final static int initialCapacity = 1*1024*1024; private final static String key_time_mills = "timeMills"; private static LinkedHashMap<String, Long> cacheTimeMills; private final static String key_time_valid = "timeValid"; private static LinkedHashMap<String, Long> cacheTimeValid;
改写接口代码:
protected boolean postCheck(final Context context, final boolean isShow, final String content,PostUrlInfo postUrlInfo,final RequestParams params, final IParser iParse, final INetCallBack callBack){ //如果不使用缓存,网络加载 if(postUrlInfo.isEnabledCache()==false) return false; //尝试获取缓存数据,如果缓存未过期,重点在get方法里; String response = Reservoir.get(postUrlInfo.reqIndentKey, String.class); if(TextUtils.isEmpty(response)) return false; //直接使用网络层正常解析方法,但标记为缓存加载 //不在放入缓存,做一些处理; DialogFragment dialogFragment = new ProgressDialogFragment(content); ParseResult parseResult = new ParseResult(); parseResult.isNetParse = false; parseTask task = new parseTask(dialogFragment, iParse, callBack, 0,getDefaultHeaders(params), response,postUrlInfo,parseResult); task.execute(); //做原网络解析,返回不在进行网络加载; return true; } //重新整理原接口,将Url信息封装,方便计算key; protected void post(final Context context, final boolean isShow, final String content,String relativePath,final RequestParams params, final IParser iParse, final INetCallBack callBack) { PostUrlInfo urlInfo = new PostUrlInfo(BaseURL,relativePath); post(context, isShow, content,urlInfo, params, iParse, callBack); } //添加一个缓存时间扩展原接口,检查cacheTime CacheEnable()方法; protected void post(long cacheTime,final Context context, final boolean isShow, final String content,String relativePath,final RequestParams params, final IParser iParse, final INetCallBack callBack) { //也可以使用host:port:ralaUrl的方式,已封装看情况; PostUrlInfo urlInfo = new PostUrlInfo(BaseURL,relativePath); urlInfo.setDefaultCacheTime(cacheTime); post(context, isShow, content,urlInfo, params, iParse, callBack); } //真实加载方式 protected void post(final Context context, final boolean isShow, final String content,final PostUrlInfo postUrlInfo,final RequestParams params, final IParser iParse, final INetCallBack callBack) { if(params == null) { return; } Logger.i(postUrlInfo.getPostUrl()); Logger.i(params.toString()); //计算该次接口的key值,检查缓存,getReqIdentifiter可去除要计算 //的postKey,比如单次随机数等; postUrlInfo.reqIndentKey = getReqIdentifiter(postUrlInfo,params); if(postCheck(context, isShow, content,postUrlInfo, params, iParse, callBack)){ return ; } //使用网络加载后,将网络层数据放入缓存 //Reservoir.put(postUrlInfo.reqIndentKey, //response,postUrlInfo.getDefaultCacheTime()); //正常网络加载 client.post(context, postUrlInfo.getPostUrl(), (org.apache.http.Header[]) getDefaultHeaders(params), params,null, new AsyncHttpResponseHandler() {};
一个JAVA AES加密的代码文件 EnDecrypt.java
package com.anupcowkur.reservoir;import java.io.UnsupportedEncodingException;import java.math.BigInteger;import java.security.InvalidKeyException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;public class EnDecrypt { public static String encrypts(String sourContent,String password){ try{ byte[] encryptResult = encrypt(sourContent, password); return parseByte2HexStr(encryptResult); }catch(Exception ex){ return sourContent; } } public static String decrypts(String cryContent,String password){ try{ byte[] decryptFrom = parseHexStr2Byte(cryContent); byte[] decryptResult = decrypt(decryptFrom,password); return new String(decryptResult); }catch(Exception ex){ return cryContent; } } private static byte[] encrypt(String content, String password) throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128, new SecureRandom(password.getBytes())); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES");// 创建密码器 byte[] byteContent = content.getBytes("utf-8"); cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化 byte[] result = cipher.doFinal(byteContent); return result; // 加密 } private static byte[] decrypt(byte[] content, String password) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128, new SecureRandom(password.getBytes())); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES");// 创建密码器 cipher.init(Cipher.DECRYPT_MODE, key);// 初始化 byte[] result = cipher.doFinal(content); return result; // 加密 } private static String parseByte2HexStr(byte buf[]) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < buf.length; i++) { String hex = Integer.toHexString(buf[i] & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } sb.append(hex.toUpperCase()); } return sb.toString(); } private static byte[] parseHexStr2Byte(String hexStr) { if (hexStr.length() < 1) return null; byte[] result = new byte[hexStr.length()/2]; for (int i = 0;i< hexStr.length()/2; i++) { int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16); int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16); result[i] = (byte) (high * 16 + low); } return result; } public static String md5(String s) { try { MessageDigest m = MessageDigest.getInstance("MD5"); m.update(s.getBytes("UTF-8")); byte[] digest = m.digest(); BigInteger bigInt = new BigInteger(1, digest); return bigInt.toString(16); } catch (NoSuchAlgorithmException e) { throw new AssertionError(); } catch (UnsupportedEncodingException e) { throw new AssertionError(); } }}