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 缓存的编写应用的主要内容,如果未能解决你的问题,请参考以下文章