編輯:關於Android編程
官方簡介:
ASimpleCache 是一個為android制定的 輕量級的 開源緩存框架。輕量到只有一個java文件(由十幾個類精簡而來)。
(有個問題是作者所說的自動失效,其實是在獲取數據時判斷存入緩存的數據是否過期,如果過期,則刪除數據緩存,返回null。當然,如果真正的自動刪除,應該只能開啟服務,不斷判斷是否過期來刪除吧,也沒有必要)
--------------------------------------------------------------------------------
1、它可以緩存什麼東西?
普通的字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java對象,和 byte數據。
2、它有什麼特色?
特色主要是:
1:輕,輕到只有一個JAVA文件。
2:可配置,可以配置緩存路徑,緩存大小,緩存數量等。
3:可以設置緩存超時時間,緩存超時自動失效,並被刪除。
4:支持多進程。
3、它在android中可以用在哪些場景?
1、替換SharePreference當做配置文件
2、可以緩存網絡請求數據,比如oschina的android客戶端可以緩存http請求的新聞內容,緩存時間假設為1個小時,超時後自動失效,讓客戶端重新請求新的數據,減少客戶端流量,同時減少服務器並發量。
3、您來說...
4、如何使用 ASimpleCache?
以下有個小的demo,希望您能喜歡:
ACache mCache = ACache.get(this);
mCache.put(test_key1, test value);
mCache.put(test_key2, test value, 10);//保存10秒,如果超過10秒去獲取這個key,將為null
mCache.put(test_key3, test value, 2 * ACache.TIME_DAY);//保存兩天,如果超過兩天去獲取這個key,將為null
獲取數據
ACache mCache = ACache.get(this);
String value = mCache.getAsString(test_key1);
主要分析下集萬千寵愛於一身的ACache類吧(以字符串存儲為例)
一,首先先要創建緩存
get(Context ctx, String cacheName)方法新建緩存目錄
get(File cacheDir, long max_zise, int max_count)方法新建緩存實例,存入實例map,key為緩存目錄加上每次應用開啟的進程id
public static ACache get(Context ctx) {
return get(ctx, ACache);
}
public static ACache get(Context ctx, String cacheName) {
//新建緩存目錄
///data/data/com.yangfuhai.asimplecachedemo/cache/ACache
File f = new File(ctx.getCacheDir(), cacheName);
return get(f, MAX_SIZE, MAX_COUNT);
}
public static ACache get(File cacheDir) {
return get(cacheDir, MAX_SIZE, MAX_COUNT);
}
public static ACache get(Context ctx, long max_zise, int max_count) {
File f = new File(ctx.getCacheDir(), ACache);
return get(f, max_zise, max_count);
}
public static ACache get(File cacheDir, long max_zise, int max_count) {
///data/data/com.yangfuhai.asimplecachedemo/cache/ACache
ACache manager = mInstanceMap.get(cacheDir.getAbsoluteFile() + myPid());
if (manager == null) {
manager = new ACache(cacheDir, max_zise, max_count);
//{/data/data/com.yangfuhai.asimplecachedemo/cache/ACache_4137=org.afinal.simplecache.ACache@2bc38270}
//{/data/data/com.yangfuhai.asimplecachedemo/cache/ACache_12189=org.afinal.simplecache.ACache@2bc3d890}
mInstanceMap.put(cacheDir.getAbsolutePath() + myPid(), manager);
}
return manager;
}
private static String myPid() {
return _ + android.os.Process.myPid();
}
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);
}
二,存入數據
put(String key, String value)方法寫數據到文件
put(String key, String value)方法中的mCache.put(file)方法做了如下設置
文件放入程序緩存後,統計緩存總量,總數,文件存放到文件map中(value值為文件最後修改時間,便於根據設置的銷毀時間進行銷毀)
緩存沒有超過限制,則增加緩存總量,總數的數值
緩存超過限制,則減少緩存總量,總數的數值
通過removeNext方法找到最老文件的大小
public void put(String key, String value) {
File file = mCache.newFile(key);
BufferedWriter out = null;
try {
out = new BufferedWriter(new FileWriter(file), 1024);
out.write(value);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
mCache.put(file);
}
}
//文件放入程序緩存後,統計緩存總量,總數,文件存放到文件map中(value值為文件最後修改時間,便於根據設置的銷毀時間進行銷毀)
//緩存沒有超過限制,則增加緩存總量,總數的數值
//緩存超過限制,則減少緩存總量,總數的數值
//通過removeNext方法找到最老文件的大小
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);
}
/**
* 移除舊的文件(冒泡,找到最後修改時間最小的文件)
*
* @return
*/
private long removeNext() {
if (lastUsageDates.isEmpty()) {
return 0;
}
Long oldestUsage = null;
File mostLongUsedFile = null;
Set> entries = lastUsageDates.entrySet();
synchronized (lastUsageDates) {
for (Entry 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;
}
三,獲取數據
getAsString(String key)方法從緩存文件中讀取數據,其中通過Utils.isDue(readString)方法判斷數據是否過期,是否要刪除
public String getAsString(String key) {
///data/data/com.yangfuhai.asimplecachedemo/cache/ACache/1727748931
File file = mCache.get(key);
if (!file.exists())
return null;
boolean removeFile = false;
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(file));
String readString = ;
String currentLine;
while ((currentLine = in.readLine()) != null) {
readString += currentLine;
}
if (!Utils.isDue(readString)) {
return Utils.clearDateInfo(readString);
} else {
removeFile = true;
return null;
}
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (removeFile)
remove(key);
}
}
/**
* 判斷緩存的String數據是否到期
*
* @param str
* @return true:到期了 false:還沒有到期
*/
private static boolean isDue(String str) {
return isDue(str.getBytes());
}
/**
* 判斷緩存的byte數據是否到期(到期:當前時間大於保存時間加上保存後的存留時間)
*
* @param data
* @return true:到期了 false:還沒有到期
*/
private static boolean isDue(byte[] data) {
String[] strs = getDateInfoFromDate(data);
if (strs != null && strs.length == 2) {
String saveTimeStr = strs[0];
while (saveTimeStr.startsWith(0)) {
saveTimeStr = saveTimeStr.substring(1, saveTimeStr.length());
}
long saveTime = Long.valueOf(saveTimeStr);
long deleteAfter = Long.valueOf(strs[1]);
if (System.currentTimeMillis() > saveTime + deleteAfter * 1000) {
return true;
}
}
return false;
}
//數據有無存留時間設置
private static boolean hasDateInfo(byte[] data) {
return data != null && data.length > 15 && data[13] == '-' && indexOf(data, mSeparator) > 14;
}
//saveDate文件保存時間毫秒數,deleteAfter文件保存後的保留時間毫秒數
private static String[] getDateInfoFromDate(byte[] data) {
if (hasDateInfo(data)) {
String saveDate = new String(copyOfRange(data, 0, 13));
String deleteAfter = new String(copyOfRange(data, 14, indexOf(data, mSeparator)));
return new String[] { saveDate, deleteAfter };
}
return null;
}
android開發筆記之高級主題—傳感器的簡單介紹
今天我們開始進入講解android中的一些高級主題的用法,比如傳感器、GPS、NFC、語音和人臉識別等。這次來對傳感器的一個簡單介紹:Android平台支持三大類的傳感器
解析android中include標簽的使用
在一個項目中我們可能會需要用到相同的布局設計,如果都寫在一個xml文件中,代碼顯得很冗余,並且可讀性也很差,所以我們可以把相同布局的代碼單獨寫成一個模塊,然後用到的時候可
Android webview和js互相調用實現方法
Android-webview和js互相調用Android 和 H5 都是移動開發應用的非常廣泛。市面上很多App都是使用Android開發的,但使用Android來開發
Android獲取asset下的資源圖片
package cc.testasset; import java.io.InputStream; import android.os.Bundle; import