sp
,有的用mmkv
,有的用lru
,有的用DataStore
,有的用sqlite
,如何打造通用api切换操作不同存储方案?LruCache
,其实缓存最初是针对于网络而言的,也是狭义上的缓存,广义的缓存是指对数据的复用。LruCache
将图片保存在内存,存取速度较快,退出APP后缓存会失效;而DiskLruCache
将图片保存在磁盘中,下次进入应用后缓存依旧存在,它的存取速度相比LruCache
会慢上一些。RecyclerView
的缓存采用了此策略。Glide
在进行内存缓存的时候采用了此策略。Context.getSharedPreferences()
进行初始化时,对xml
文件进行一次读取,并将文件内所有内容(即所有的键值对)缓到内存的一个Map
中,接下来所有的读操作,只需要从这个Map
中取就可以//获取数据
boolean data1 = dataCache.readBoolean("cacheKey1", false);
float data2 = dataCache.readFloat("cacheKey2", 0);
int data3 = dataCache.readInt("cacheKey3", 0);
long data4 = dataCache.readLong("cacheKey4", 0);
String data5 = dataCache.readString("cacheKey5", "");
double data6 = dataCache.readDouble("cacheKey5", 0.0);
```
//如何使用
object CacheHelper {
//常规缓存数据,记录一些重要的信息,慎重清除数据
private val normal: NormalCache by lazy {
NormalCache().apply {
setCacheImpl(
DiskCache.Builder()
.setFileId("NormalCache")
.build()
)
}
}
fun normal() = normal
}
//存数据
CacheHelper.normal().hasAcceptParentAgree = true
//取数据
val hasAccept = CacheHelper.normal().hasAcceptParentAgree
```
> SharedPreferencesImpl#enqueueDiskWrite(),这个会将runnable被写入了队列,然后在run方法中写数据到磁盘
> QueuedWork#queue(),这个将runnable添加到sWork(LinkedList链表)中,然后通过handler发送处理队列消息MSG_RUN
- 然后再看一下ActivityThread源码中的handlePauseActivity()、handleStopActivity()方法。
> ActivityThread#handlePauseActivity()/handleStopActivity(),Activity在pause和stop的时候会调用该方法
> ActivityThread#handlePauseActivity()#QueuedWork.waitToFinish(),这个是等待QueuedWork所有任务处理完的逻辑
> QueuedWork#waitToFinish(),这个里面会通过handler查询MSG_RUN消息是否有,如果有则会waiting等待
- 那么最后得出的结论是
- handlePauseActivity()的时候会一直等待 apply() 方法将数据保存成功,否则会一直等待,从而阻塞主线程造成 ANR。但普通存储的场景,这种可能性很小。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。