轉載請標明出處:
http://www.lxweimin.com/p/f757b671ed3b
本文出自:【江清清博客-代號獨狼】
(一)寫在前面的話
接著上一篇繼續(xù)更新,上一篇文章已經把FastDev4Android項目列表下拉刷新組件(PullToRefreshListView)組件做了講解和使用。今天項目更新是得數據緩存器(ACache)的詳解和使用。
該詳解實例已經同步到FastDev4Android項目中了地址為:
[https://github.com/jiangqqlmj/FastDev4Android]
(二):功能介紹
2.1:基本介紹 ACache項目是我去年在Github上面發(fā)現的一個開源項目,首先感謝作者,感謝Github開源的力量。ACache是一個比較輕量級的數據緩存管理器(一個類ACache.java)解決問題,所以學習起來就非常簡單,在中小型項目中可以較好的去使用。ACache使用采用手機包名路徑下文件數據保存方式進行數據緩存,同時可以自定義設置數據緩存的路徑,緩存的文件大小,以及緩存的文件數量以及相應的緩存過期時間。下面我們來看一下整個類中相應的方法和變量以及常量,這樣對整個類有一個直觀的了解。
查看以上各種方法,我們可以知道ACache給我們提供了文本數據,JSON格式數據,圖片等信息緩存,當然我們也可以通過實際的項目情況,對該類進行其他格式數據的擴展。
2.2:ACache流程 ACache請求處理流程
(三):核心方法介紹
3.1:相關配置數據設置
public static final int TIME_HOUR = 60 * 60; //緩存一個小時
public static final int TIME_MINUTE = 60; //混存一分鐘
public static final int TIME_DAY = TIME_HOUR * 12; //緩存一個白天 12個小時
private static final int MAX_SIZE = 1000 * 1000 * 50; // 50 mb
private static final int MAX_COUNT = Integer.MAX_VALUE; // 不限制存放數據的數量
以上可以自定義設置緩存時間,緩存文件大小和限制存放數據的數量等信息
3.2:靜態(tài)獲取ACache對象實現方法
public static ACache get(Context ctx)
public static ACache get(Context ctx, String cacheName)
public static ACache get(File cacheDir)
public static ACache get(Context ctx, long max_zise, int max_count)
使用者可以根據不同的參數分別獲取ACache管理對象。
3.3:ACache對象創(chuàng)建方法:
①:對象獲取
public static ACache get(File cacheDir, long max_zise, int max_count) {
ACache manager = mInstanceMap.get(cacheDir.getAbsoluteFile() + myPid());
if (manager == null) {
manager = new ACache(cacheDir, max_zise, max_count);
mInstanceMap.put(cacheDir.getAbsolutePath() + myPid(), manager);
}
return manager;
}
根據以上代碼可以知道在創(chuàng)建ACache對象的時候,會先通過Map Cache緩存中去查找是否已經存在該對象,有直接返回,如果不存在那么進行創(chuàng)建對象實例(通過new ACache(xxx,xx,xx)),然后保存一份到Map緩存中。
②:?對象創(chuàng)建
private ACache(File cacheDir, long max_size, int max_count) {
if (!cacheDir.exists() && !cacheDir.mkdirs()) {
throw new RuntimeException("can't make dirs in " + cacheDir.getAbsolutePath());
}
mCache = new ACacheManager(cacheDir, max_size, max_count);
}
以上代碼可以得知最終我們使用的管理器就是ACacheManager實例,在這邊進行緩存器的初始化(文件路徑,緩存數量,緩存大小)以及數據最終保存和獲取。那么最后我們來看一下整個ACacheManger的實現代碼吧:
public class ACacheManager {
private final AtomicLong cacheSize;
private final AtomicInteger cacheCount;
private final long sizeLimit;
private final int countLimit;
private final Map<File, Long> lastUsageDates = Collections
.synchronizedMap(new HashMap<File, Long>());
protected File cacheDir;
private ACacheManager(File cacheDir, long sizeLimit, int countLimit) {
this.cacheDir = cacheDir;
this.sizeLimit = sizeLimit;
this.countLimit = countLimit;
cacheSize = new AtomicLong();
cacheCount = new AtomicInteger();
calculateCacheSizeAndCacheCount();
}
/**
* 計算 cacheSize和cacheCount
*/
private void calculateCacheSizeAndCacheCount() {
new Thread(new Runnable() {
@Override
public void run() {
int size = 0;
int count = 0;
File[] cachedFiles = cacheDir.listFiles();
if (cachedFiles != null) {
for (File cachedFile : cachedFiles) {
size += calculateSize(cachedFile);
count += 1;
lastUsageDates.put(cachedFile,
cachedFile.lastModified());
}
cacheSize.set(size);
cacheCount.set(count);
}
}
}).start();
}
private void put(File file) {
int curCacheCount = cacheCount.get();
while (curCacheCount + 1 > countLimit) {
long freedSize = removeNext();
cacheSize.addAndGet(-freedSize);
curCacheCount = cacheCount.addAndGet(-1);
}
cacheCount.addAndGet(1);
long valueSize = calculateSize(file);
long curCacheSize = cacheSize.get();
while (curCacheSize + valueSize > sizeLimit) {
long freedSize = removeNext();
curCacheSize = cacheSize.addAndGet(-freedSize);
}
cacheSize.addAndGet(valueSize);
Long currentTime = System.currentTimeMillis();
file.setLastModified(currentTime);
lastUsageDates.put(file, currentTime);
}
private File get(String key) {
File file = newFile(key);
Long currentTime = System.currentTimeMillis();
file.setLastModified(currentTime);
lastUsageDates.put(file, currentTime);
return file;
}
private File newFile(String key) {
return new File(cacheDir, key.hashCode() + "");
}
private boolean remove(String key) {
File image = get(key);
return image.delete();
}
private void clear() {
lastUsageDates.clear();
cacheSize.set(0);
File[] files = cacheDir.listFiles();
if (files != null) {
for (File f : files) {
f.delete();
}
}
}
/**
* 移除舊的文件
*
* @return
*/
private long removeNext() {
if (lastUsageDates.isEmpty()) {
return 0;
}
Long oldestUsage = null;
File mostLongUsedFile = null;
Set<Map.Entry<File, Long>> entries = lastUsageDates.entrySet();
synchronized (lastUsageDates) {
for (Map.Entry<File, Long> entry : entries) {
if (mostLongUsedFile == null) {
mostLongUsedFile = entry.getKey();
oldestUsage = entry.getValue();
} else {
Long lastValueUsage = entry.getValue();
if (lastValueUsage < oldestUsage) {
oldestUsage = lastValueUsage;
mostLongUsedFile = entry.getKey();
}
}
}
}
long fileSize = calculateSize(mostLongUsedFile);
if (mostLongUsedFile.delete()) {
lastUsageDates.remove(mostLongUsedFile);
}
return fileSize;
}
private long calculateSize(File file) {
return file.length();
}
}
(四):使用介紹
我們在使用該工具的時候,很簡單,獲取對象實例,做put和get操作即可 ACache mACache=ACache.get(Contenxt) 默認獲取方式,或者可以采用另外幾個靜態(tài)獲取方法也可以,下面我們來看一下具體實現。
private Button save_cache;
private Button query_cache;
private EditText edit_cache;
private TextView tv_cache;
private ACache mAcache;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sp_cache_layout);
save_cache=(Button)this.findViewById(R.id.save_cache);
query_cache=(Button)this.findViewById(R.id.query_cache);
edit_cache=(EditText)this.findViewById(R.id.edit_cache);
tv_cache=(TextView)this.findViewById(R.id.tv_cache);
mAcache=ACache.get(this);
//進行保存數據
save_cache.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String save_str = edit_cache.getText().toString().trim();
mAcache.put(CacheConsts.DEMO_CACHE_KEY, save_str);
showToastMsgShort("緩存成功...");
}
});
//進行查詢數據
query_cache.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String query_str=mAcache.getAsString(CacheConsts.DEMO_CACHE_KEY);
tv_cache.setText(query_str);
}
});
}
運行結果如下:
到此為止我們今天ACache的講解和使用結果,詳細代碼項目地址:
https://github.com/jiangqqlmj/FastDev4Android 同時歡迎大家star和fork整個開源快速開發(fā)框架項目~如果有什么意見和反饋,歡迎留言,必定第一時間回復。也歡迎有同樣興趣的童鞋加入到該項目中來,一起維護該項目。