一、持久化方式:
-  
DataStore:稳定性
 -  
MMKV:效率
 -  
SharedPreferneces
 
区别:
| 功能 | MMKV | Jetpack DataStore | SharedPreferneces | 
|---|---|---|---|
| 是否阻塞主线程 | 否 | 否 | 是 | 
| 是否线程安全 | 是 | 是 | 是 | 
| 是否支持跨进程 | 是 | 否 | 否 | 
| 是否类型安全 | 否 | 是 | 否 | 
| 是否支持protocol buffers | 是 | 是 | 否 | 
| 是否能监听数据变化 | 否 | 是 | 是 | 
二、SharedPreferences存储流程:
-  
k,v -> 存储到文件里
 -  
序列化:XML JSON PROTOBUFF…
 -  
IO
 
三、SP的系统源码分析--调用流程
getSharedPreferences("test",MODE_PRIVATE)
-  
Context#getSharedPreferences --> Context的实现类 --ContextImpl#getSharedPreferences中去new SharedPreferencesImpl对象 ContextWrapper 用到装饰者模式
 -  
SharedPreferencesImpl#startLoadFromDisk(),用一个同步代码块synchronized 将 mLoaded = false; (mLoaded -> 加载是否完成)
 -  
同时启动一个子线程去进行IO操作,子线程中调用loadFromDisk,去进行数据的加载 str = new BufferedInputStream(new FileInputStream(mFile), 16 * 1024) IO体系 用到装饰者模式
 -  
读数据:读出来之后加载到内存中,放到一个全局的HashMap变量mMap -- 因此SP读取数据的效率是非常高的
 -  
取数据:
 -  
每次取数据都会调用一下edit方法,内部都会new EditorImpl
 -  
得到edit之后,调用put()保存,将k v数据放到临时的map集合里mM
 -  
保存完了之后调用commit,apply
 -  
commit:boolean 同步 当CPU忙,达到峰值,数据大,会产生ANR
 -  
apply: void 异步 也会产生ANR
 
注意:
在使用SP的时候,不要频繁的调用edit,如在for循环里、view#onDraw,gc频繁运行,可能会导致程序卡顿,如果GC选择的回收对象算法是标记清除算法,可能导致程序出现OOM导致内存碎片的产生。
分析:
Apply异步产生ANR的原因 -- Activity跳转时,apply提交会包装成Runnable:任务 -> QueuedWork:队列 排队执行 ->会执行QueuedWork.waitToFinish:等待QueuedWork中的任务全部执行完
AActivity ->BActivity
A:onPause -> B:onCreate onStart onResume -> A:onStop
疑问:
生命周期是怎么被调起的?/ Activity启动流程
AMS -> Binder -> ActivityThread#ApplicationThread->对应的方法 -> handler -> 调用
总结:
|   特点  |   说明  | 
|   数据格式  |   XML格式保存  | 
|   初始化  |   子线程使用IO读取整个文件,进行XML解析,存入内存Map集合  | 
|   保存  |   commit同步提交,阻塞主线程;apply异步提交,无法获取结果且可能数据丢失  | 
|   更新  |   把Map中的数据,全部序列化为XML,覆盖文件保存(全量更新)  | 
优化方向:
-  
比XML更精简的数据格式,XML繁琐,冗余数据多,数据量大
 -  
高效的文件操作 -- 传统IO 高效的NIO(零拷贝) FileChannel,transformTO
 -  
更优的数据更新方式 -- 局部更新
 










