|
|
@ -23,7 +23,49 @@ import kotlin.math.min |
|
|
|
* 本地缓存 |
|
|
|
* 本地缓存 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int) { |
|
|
|
class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int) { |
|
|
|
private lateinit var mCache: ACacheManager |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
companion object { |
|
|
|
|
|
|
|
const val TIME_HOUR = 60 * 60 |
|
|
|
|
|
|
|
const val TIME_DAY = TIME_HOUR * 24 |
|
|
|
|
|
|
|
private const val MAX_SIZE = 1000 * 1000 * 50 // 50 mb |
|
|
|
|
|
|
|
private const val MAX_COUNT = Integer.MAX_VALUE // 不限制存放数据的数量 |
|
|
|
|
|
|
|
private val mInstanceMap = HashMap<String, ACache>() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads |
|
|
|
|
|
|
|
fun get( |
|
|
|
|
|
|
|
ctx: Context, |
|
|
|
|
|
|
|
cacheName: String = "ACache", |
|
|
|
|
|
|
|
maxSize: Long = MAX_SIZE.toLong(), |
|
|
|
|
|
|
|
maxCount: Int = MAX_COUNT, |
|
|
|
|
|
|
|
cacheDir: Boolean = true |
|
|
|
|
|
|
|
): ACache { |
|
|
|
|
|
|
|
val f = if (cacheDir) File(ctx.cacheDir, cacheName) else File(ctx.filesDir, cacheName) |
|
|
|
|
|
|
|
return get(f, maxSize, maxCount) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads |
|
|
|
|
|
|
|
fun get( |
|
|
|
|
|
|
|
cacheDir: File, |
|
|
|
|
|
|
|
maxSize: Long = MAX_SIZE.toLong(), |
|
|
|
|
|
|
|
maxCount: Int = MAX_COUNT |
|
|
|
|
|
|
|
): ACache { |
|
|
|
|
|
|
|
synchronized(this) { |
|
|
|
|
|
|
|
var manager = mInstanceMap[cacheDir.absoluteFile.toString() + myPid()] |
|
|
|
|
|
|
|
if (manager == null) { |
|
|
|
|
|
|
|
manager = ACache(cacheDir, maxSize, maxCount) |
|
|
|
|
|
|
|
mInstanceMap[cacheDir.absolutePath + myPid()] = manager |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return manager |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun myPid(): String { |
|
|
|
|
|
|
|
return "_" + android.os.Process.myPid() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private var mCache: ACacheManager? = null |
|
|
|
|
|
|
|
|
|
|
|
init { |
|
|
|
init { |
|
|
|
try { |
|
|
|
try { |
|
|
@ -48,12 +90,14 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int) |
|
|
|
* @param value 保存的String数据 |
|
|
|
* @param value 保存的String数据 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun put(key: String, value: String) { |
|
|
|
fun put(key: String, value: String) { |
|
|
|
try { |
|
|
|
mCache?.let { mCache -> |
|
|
|
val file = mCache.newFile(key) |
|
|
|
try { |
|
|
|
file.writeText(value) |
|
|
|
val file = mCache.newFile(key) |
|
|
|
mCache.put(file) |
|
|
|
file.writeText(value) |
|
|
|
} catch (e: Exception) { |
|
|
|
mCache.put(file) |
|
|
|
e.printStackTrace() |
|
|
|
} catch (e: Exception) { |
|
|
|
|
|
|
|
e.printStackTrace() |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -74,24 +118,26 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int) |
|
|
|
* @return String 数据 |
|
|
|
* @return String 数据 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun getAsString(key: String): String? { |
|
|
|
fun getAsString(key: String): String? { |
|
|
|
val file = mCache[key] |
|
|
|
mCache?.let { mCache -> |
|
|
|
if (!file.exists()) |
|
|
|
val file = mCache[key] |
|
|
|
return null |
|
|
|
if (!file.exists()) |
|
|
|
var removeFile = false |
|
|
|
return null |
|
|
|
return try { |
|
|
|
var removeFile = false |
|
|
|
val text = file.readText() |
|
|
|
try { |
|
|
|
if (!Utils.isDue(text)) { |
|
|
|
val text = file.readText() |
|
|
|
Utils.clearDateInfo(text) |
|
|
|
if (!Utils.isDue(text)) { |
|
|
|
} else { |
|
|
|
return Utils.clearDateInfo(text) |
|
|
|
removeFile = true |
|
|
|
} else { |
|
|
|
null |
|
|
|
removeFile = true |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} catch (e: IOException) { |
|
|
|
|
|
|
|
e.printStackTrace() |
|
|
|
|
|
|
|
} finally { |
|
|
|
|
|
|
|
if (removeFile) |
|
|
|
|
|
|
|
remove(key) |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (e: IOException) { |
|
|
|
|
|
|
|
null |
|
|
|
|
|
|
|
} finally { |
|
|
|
|
|
|
|
if (removeFile) |
|
|
|
|
|
|
|
remove(key) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return null |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ======================================= |
|
|
|
// ======================================= |
|
|
@ -184,9 +230,11 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int) |
|
|
|
* @param value 保存的数据 |
|
|
|
* @param value 保存的数据 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun put(key: String, value: ByteArray) { |
|
|
|
fun put(key: String, value: ByteArray) { |
|
|
|
val file = mCache.newFile(key) |
|
|
|
mCache?.let { mCache -> |
|
|
|
file.writeBytes(value) |
|
|
|
val file = mCache.newFile(key) |
|
|
|
mCache.put(file) |
|
|
|
file.writeBytes(value) |
|
|
|
|
|
|
|
mCache.put(file) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -206,26 +254,28 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int) |
|
|
|
* @return byte 数据 |
|
|
|
* @return byte 数据 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun getAsBinary(key: String): ByteArray? { |
|
|
|
fun getAsBinary(key: String): ByteArray? { |
|
|
|
var removeFile = false |
|
|
|
mCache?.let { mCache -> |
|
|
|
try { |
|
|
|
var removeFile = false |
|
|
|
val file = mCache[key] |
|
|
|
try { |
|
|
|
if (!file.exists()) |
|
|
|
val file = mCache[key] |
|
|
|
return null |
|
|
|
if (!file.exists()) |
|
|
|
|
|
|
|
return null |
|
|
|
|
|
|
|
|
|
|
|
val byteArray = file.readBytes() |
|
|
|
val byteArray = file.readBytes() |
|
|
|
return if (!Utils.isDue(byteArray)) { |
|
|
|
return if (!Utils.isDue(byteArray)) { |
|
|
|
Utils.clearDateInfo(byteArray) |
|
|
|
Utils.clearDateInfo(byteArray) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
removeFile = true |
|
|
|
removeFile = true |
|
|
|
null |
|
|
|
null |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} catch (e: Exception) { |
|
|
|
|
|
|
|
e.printStackTrace() |
|
|
|
|
|
|
|
} finally { |
|
|
|
|
|
|
|
if (removeFile) |
|
|
|
|
|
|
|
remove(key) |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (e: Exception) { |
|
|
|
|
|
|
|
e.printStackTrace() |
|
|
|
|
|
|
|
return null |
|
|
|
|
|
|
|
} finally { |
|
|
|
|
|
|
|
if (removeFile) |
|
|
|
|
|
|
|
remove(key) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return null |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -269,7 +319,6 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int) |
|
|
|
return ois.readObject() |
|
|
|
return ois.readObject() |
|
|
|
} catch (e: Exception) { |
|
|
|
} catch (e: Exception) { |
|
|
|
e.printStackTrace() |
|
|
|
e.printStackTrace() |
|
|
|
return null |
|
|
|
|
|
|
|
} finally { |
|
|
|
} finally { |
|
|
|
try { |
|
|
|
try { |
|
|
|
bais?.close() |
|
|
|
bais?.close() |
|
|
@ -371,15 +420,16 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int) |
|
|
|
* @return value 缓存的文件 |
|
|
|
* @return value 缓存的文件 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun file(key: String): File? { |
|
|
|
fun file(key: String): File? { |
|
|
|
try { |
|
|
|
mCache?.let { mCache -> |
|
|
|
val f = mCache.newFile(key) |
|
|
|
try { |
|
|
|
if (f.exists()) { |
|
|
|
val f = mCache.newFile(key) |
|
|
|
return f |
|
|
|
if (f.exists()) { |
|
|
|
|
|
|
|
return f |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} catch (e: Exception) { |
|
|
|
|
|
|
|
e.printStackTrace() |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (e: Exception) { |
|
|
|
|
|
|
|
e.printStackTrace() |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return null |
|
|
|
return null |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -389,14 +439,14 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int) |
|
|
|
* @return 是否移除成功 |
|
|
|
* @return 是否移除成功 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun remove(key: String): Boolean { |
|
|
|
fun remove(key: String): Boolean { |
|
|
|
return mCache.remove(key) |
|
|
|
return mCache?.remove(key) == true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* 清除所有数据 |
|
|
|
* 清除所有数据 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun clear() { |
|
|
|
fun clear() { |
|
|
|
mCache.clear() |
|
|
|
mCache?.clear() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -726,44 +776,4 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
companion object { |
|
|
|
|
|
|
|
const val TIME_HOUR = 60 * 60 |
|
|
|
|
|
|
|
const val TIME_DAY = TIME_HOUR * 24 |
|
|
|
|
|
|
|
private const val MAX_SIZE = 1000 * 1000 * 50 // 50 mb |
|
|
|
|
|
|
|
private const val MAX_COUNT = Integer.MAX_VALUE // 不限制存放数据的数量 |
|
|
|
|
|
|
|
private val mInstanceMap = HashMap<String, ACache>() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads |
|
|
|
|
|
|
|
fun get( |
|
|
|
|
|
|
|
ctx: Context, |
|
|
|
|
|
|
|
cacheName: String = "ACache", |
|
|
|
|
|
|
|
maxSize: Long = MAX_SIZE.toLong(), |
|
|
|
|
|
|
|
maxCount: Int = MAX_COUNT, |
|
|
|
|
|
|
|
cacheDir: Boolean = true |
|
|
|
|
|
|
|
): ACache { |
|
|
|
|
|
|
|
val f = if (cacheDir) File(ctx.cacheDir, cacheName) else File(ctx.filesDir, cacheName) |
|
|
|
|
|
|
|
return get(f, maxSize, maxCount) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads |
|
|
|
|
|
|
|
fun get( |
|
|
|
|
|
|
|
cacheDir: File, |
|
|
|
|
|
|
|
maxSize: Long = MAX_SIZE.toLong(), |
|
|
|
|
|
|
|
maxCount: Int = MAX_COUNT |
|
|
|
|
|
|
|
): ACache { |
|
|
|
|
|
|
|
synchronized(this) { |
|
|
|
|
|
|
|
var manager = mInstanceMap[cacheDir.absoluteFile.toString() + myPid()] |
|
|
|
|
|
|
|
if (manager == null) { |
|
|
|
|
|
|
|
manager = ACache(cacheDir, maxSize, maxCount) |
|
|
|
|
|
|
|
mInstanceMap[cacheDir.absolutePath + myPid()] = manager |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return manager |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun myPid(): String { |
|
|
|
|
|
|
|
return "_" + android.os.Process.myPid() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |