Android 缓存的编写应用

我们都知道一个APP是不能没有缓存的,而一般而言,一个Android项目的缓存主要体现在数据缓存和图片缓存两点,我们一点点的讲.

数据缓存

首先我们要有个思想就是:一个应用类的APP,如果在2G或者3G网络下面访问的特别慢,那么这个APP就是失败的,不要使用wifi去测APP的反应速度,这种会造成,APP反应速度很快的假象,算不得真是数据。

访问API,慢就慢在一来一回的请求和返回上面。服务器的反应速度我们暂且不说,我们只说客户端的。

数据传输耗的时间比较多,我们就从数据传输的方面来提高数据传输的速度:

  • 减少API调用次数,一个界面上的API调用次数太多会造成反应慢的结果,所以我们在定义API的时候尽量让数据整合,一个接口能获取到5个参数,就不要获取3个,数据尽量一次性返回。
  • APP缓存,就是在APP调用API接口的一段时间内不再调用这个接口了,在这个时间段之内用的是上一次请求获取到的数据,这个就叫做APP缓存,这个时间段就是缓存时间。

App缓存只能针对get类型的接口,因为GET是获取数据。POST是修改数据。

此外,对于那些即时性很低的,很长时间都不会变化的数据,缓存时间可以适当的长一点,10分钟左右是个很好的选择,但是对于即时性比较高,频繁变动的数据来说,缓存的时间就要设置的相对短一点,甚至不设置缓存。

App缓存应该到哪里存放呢。由于缓存数据比较大,我们将其放在SD卡里面,而不是内存里,这样的话,App缓存策略就仅限有哪些有SD卡的手机用户了。

所以这个数据缓存我们需要注意的是:

  • 对于APP而言,APP是感受不到取得是缓存数据还是API返回的数据,具体的缓存操作在网络请求中完成。
  • 给App网络框架提供一个缓存时间参数,并且在请求方式为POST的时候为0
  • 要在网络框架里加一个排序的方法,这个方法可以有效的防止重复缓存数据
  • 在缓存时间内,在网络框架中先检查缓存是不是有数据,有的话直接返回,没有在去请求API

缓存工具类的代码CacheManager主要用于读写缓存数据,判断缓存的数据是否已经过期:

package com.infrastructure.cache;

import java.io.File;

import android.os.Environment;
import android.util.Log;

import com.infrastructure.utils.BaseUtils;

/**
 * 缓存管理器
 */
public class CacheManager {
    private static final String TAG = "CacheManage" ;
    /** 缓存文件路径 */
    public static final String APP_CACHE_PATH = Environment
            .getExternalStorageDirectory().getPath() + "/mabin/data/";

    /** sdcard 最小空间,如果小于10M,不会再向sdcard里面写入任何数据 */
    public static final long SDCARD_MIN_SPACE = 1024 * 1024 * 10;

    private static CacheManager cacheManager;

    private CacheManager() {
    }

    /**
     * 获取CacheManager实例
     *
     * @return
     */
    public static synchronized CacheManager getInstance() {
        if (CacheManager.cacheManager == null) {
            CacheManager.cacheManager = new CacheManager();
        }
        return CacheManager.cacheManager;
    }


    /**
     * 从文件缓存中取出缓存,没有则返回空
     *
     * @param key
     * @return
     */
    public String getFileCache(final String key) {
        String md5Key = BaseUtils.getMd5(key);
        if (contains(md5Key)) {
            final CacheItem item = getFromCache(md5Key);
            if (item != null) {
                return item.getData();
            }
        }
        return null;
    }

    /**
     * API data 缓存到文件
     *
     * @param key
     * @param data
     * @param expiredTime
     */
    public void putFileCache(final String key, final String data,
                             long expiredTime) {
        String md5Key = BaseUtils.getMd5(key);
        final CacheItem item = new CacheItem(md5Key, data, expiredTime);
        putIntoCache(item);
    }

    /**
     * 查询是否有key对应的缓存文件
     *
     * @param key
     * @return
     */
    public boolean contains(final String key) {
        final File file = new File(APP_CACHE_PATH + key);
        return file.exists();
    }

    public void initCacheDir() {
        // sdcard已经挂载并且空间不小于10M,可以写入文件;小于10M时,清除缓存
        if (BaseUtils.sdcardMounted()) {
            if (BaseUtils.getSDSize() < SDCARD_MIN_SPACE) {
                clearAllData();
            } else {
                final File dir = new File(APP_CACHE_PATH);
                Log.d(TAG,"makeDir=========================================") ;
                if (!dir.exists()) {
                    dir.mkdirs();
                }
            }
        }
    }

    /**
     * 将CacheItem从磁盘读取出来
     *
     * @param key
     * @return 缓存数据CachItem
     */
    synchronized CacheItem getFromCache(final String key) {
        CacheItem cacheItem = null;
        Object findItem = BaseUtils.restoreObject(APP_CACHE_PATH + key);
        if (findItem != null) {
            cacheItem = (CacheItem) findItem;
        }

        // 缓存不存在
        if (cacheItem == null)
            return null;

        // 缓存过期
        long a = System.currentTimeMillis();
        if (System.currentTimeMillis() > cacheItem.getTimeStamp()) {
            return null;
        }

        return cacheItem;
    }

    /**
     * 将CacheItem缓存到磁盘
     *
     * @param item
     * @return 是否缓存,True:缓存成功,False:不能缓存
     */

    synchronized boolean putIntoCache(final CacheItem item) {
        if (BaseUtils.getSDSize() > SDCARD_MIN_SPACE) {
            BaseUtils.saveObject(APP_CACHE_PATH + item.getKey(), item);
            return true;
        }

        return false;
    }

    /**
     * 清除缓存文件
     */
    void clearAllData() {

        File file = null;
        File[] files = null;
        if (BaseUtils.sdcardMounted()) {
            file = new File(APP_CACHE_PATH);
            files = file.listFiles();
            if (files != null) {
                for (final File file2 : files) {
                    file2.delete();
                }
            }
        }
    }
}

package com.infrastructure.cache;

import java.io.Serializable;

/**
 
 */
public class CacheItem implements Serializable {
    /** 存储的key */
    private final String key;

    /** JSON字符串 */
    private String data;

    /** 过期时间的时间戳 */
    private long timeStamp = 0L;

    public CacheItem(String key, String data, long expiredTime) {
        this.key = key;
        this.data = data;
        this.timeStamp = System.currentTimeMillis() + expiredTime * 1000;
    }

    public String getKey() {
        return key;
    }

    public String getData() {
        return data;
    }

    public long getTimeStamp() {
        return timeStamp;
    }
}
CacheItem 是缓存中存放的实体。

当然为了更好的用户体验,我们可以在客户端设置一个刷新的按钮,在点击按钮之后,页面会重新调用API加载数据,不管缓存时间是否到期。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值