Android 缓存的编写应用

Posted 鲨鱼丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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加载数据,不管缓存时间是否到期。




以上是关于Android 缓存的编写应用的主要内容,如果未能解决你的问题,请参考以下文章

Android 缓存的编写应用

Android项目实战--手机卫士35--清除程序缓存

asserts文件存到外部SD卡里

Android WebView 缓存

android应用程序的安装方式与原理

图片的缓存