android:缓存服务器数据为本地存储

文章地址: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();
        }
    }
}
时间: 2024-10-11 21:46:11

android:缓存服务器数据为本地存储的相关文章

webservice缓存服务器数据到本地,提供服务接口读取缓存的文件

遇到的问题:1.缓存到本地的文件写入一次,不能读取,不能二次写入.程序报异常:文件被占用 解决办法: FileStream fs = new FileStream(appPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);                           StreamReader sr = new StreamReader(fs, System.Text.Encoding.UTF8); 设置文件FileShar

UI_19 数据持久化(本地存储)

一.数据持久化概述 数据持久化就是数据的永久存储.其本质是将数据保存为文件,存到程序的沙盒中. 1.数据持久化的方式 1.1 writeToFile:简单对象写入文件 1.2 NSUserDefaults:应用程序偏好设置1.3 Sqlite:轻量级关系型数据库,不能直接存储对象(NSData除外),需要用到一些SQL语句,先将复杂对象归档(对象->NSData) 1.4 CoreData:对象型数据库,实质是将数据库的内部存储细节封装 1.5 Plist文件 2.应用程序沙盒 每一应用程序都有

(尚030)Vue_案例_存储数据(localStorage本地存储技术)

当刷新页面时,会变为原来的状态 1.问题:当我刷新是不希望改变原来状态 需要缓存我当前的数据 2.究竟是缓存在内存里还是在文件里??? 缓存在文件里,因为浏览器关闭了,内存就没了;而我们需要重新打开浏览器状态还在 可以用localStorage这种本地技术(本质是缓存在文件里) 3.存储带来的问题 什么时候存?什么时候读?存啥东西进去? 界面显示是根据todos显示的,所以需要将todos存起来; 我随便做任何操作后,都是我最后的状态,也就是只要我的界面发生改变就需要存(todos改变就要存)

兼容多浏览器的本地存储

在做考试系统时需要解决这样一个问题,就是当考生考试时可能出出现断网.关闭浏览器,刷新等问题,数据此时可能没有及时写入数据库,所以造成数据丢失问题,,所以这里就需要用到本地存储,以前的版本都是用cookie,但是不得不说cookie太小了,只有可怜的4k,而机房的网有时候实在是让人捉急,所以,考虑换一种方案. 直接读取XML实现方式 因为本地存储平时接触的不是太多,开始想的只是简单的读取本地的XML,做起来倒是挺容易的,一个语句就能搞定: <script language="javascri

HTML5 学习笔记(三)——本地存储

目录 一.HTML4客户端存储 1.1.提交表单发送到服务器的信息 1.2.客户端本地存储概要 二.localStorage 2.1.添加 2.2.取值 2.3.修改 2.4.删除 2.5.跨页面与跨域 2.6.存储位置与SQLite 2.7.用途.练习与兼容性 三.sessionStorage 3.1.sessionStorage使用 3.2.Web本地存储事件监听 3.3.cookie.sessionStorage.localStorage比较 四.Web SQL Database 4.1.

缓存服务器设计与实现(五)

上次讲到lru与缓存重建,这次主要讲一下关于过期处理的一些主要问题.在讨论这个问题之前,有个相关的问题需要大家有所了解.就是对于一个缓存如期只来说,什么东西应该缓存,什么不应该缓存.这是一个比较复杂的问题,涉及到http协议的诸多细节.这里赵永明大哥写了一篇文章,讲得很详细,虽然是以ATS为背景讲的,但是思路是想通的,大家可以点击[这里](https://blog.zymlinux.net/index.php/archives/1090)去看一下,文章名字很骚气叫*"to cache or no

【Android应用开发】 Android 崩溃日志 本地存储 与 远程保存

示例代码下载 : http://download.csdn.net/detail/han1202012/8638801; 一. 崩溃日志本地存储 1. 保存原理解析 崩溃信息本地保存步骤 : -- 1. 自定义类实现 UncaughtExceptionHandler : public class CrashHandler implements UncaughtExceptionHandler; -- 2. 设置该自定义的 CrashHandler 类为单例模式 : // 单例模式 private

HTML5基础扩展——地理位置、本地存储、缓存

HTML5扩展,继上两篇博客,我们来看一下HTML5的一些扩展的功能,由于HTML5更多是为了兼容电脑浏览器,安卓浏览器,苹果浏览器更多浏览器,或者说为这些浏览器提供一个统一的标准.因此目前在手机上的web开发,HTML5是比较火的.因此这几款扩展功能,感觉更多是从手机,平板等角度出发的. 一,地理定位:首先看一下地理位置的定位的几种形式:IP地址,GPS(Global Positioning System ),Wifi,GSM(Global System for Mobile Communic

android开发中的5种存储数据方式

数据存储在开发中是使用最频繁的,根据不同的情况选择不同的存储数据方式对于提高开发效率很有帮助.下面笔者在主要介绍Android平台中实现数据存储的5种方式. 1.使用SharedPreferences存储数据 SharedPreferences是Android平台上一个轻量级的存储类,主要是保存一些常用的配置比如窗口状态,一般在Activity中 重载窗口状态onSaveInstance State保存一般使用SharedPreferences完成,它提供了Android平台常规的Long长 整