全面剖析SharedPreferences

2018-07-09  本文已影响4人  暮染1

1.原理和概述

2.初始化

  1. ContextImpl记录着SharedPreferences的重要数据
    1.sSharedPrefsCache:以包名为key, 二级key是以SP文件, 以SharedPreferencesImpl为value的嵌套map结构. 这里需要sSharedPrefsCache是静态类成员变量, 每个进程是保存唯一一份, 且由ContextImpl.class锁保护.
    2.mSharedPrefsPaths:记录所有的SP文件, 以文件名为key, 具体文件为value的map结构
    3.mPreferencesDir:是指SP所在目录, 是指/data/data//shared_prefs/

  2. Context.getSharedPreferences(name, mode)获取SharedPreferences,只要是Context都能获取
    1.先从mSharedPrefsPaths查询是否存在相应文
    2.如果文件不存在, 则创建新的xml文件; 如果目录也不存在, 则先创建目录创建目录/data/data/package name/shared_prefs/

  3. 检查mode
    。1.MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE 在android N开始就会抛出异常,防止外部应用读写该文件
    。2.MODE_MULTI_PROCESS 是多进程方式使用文件,由于有内存缓存的缘故这种模式下不怎么能保证进程安全,后续google不再支持。代替的方式有ContentProvider。

  4. 创建同名的.bak备份文件用于发生异常时, 可通过备份文件来恢复数据.

  5. 将xml文件加载到内存中,这个操作的线程是新开的,但是会阻塞getXXX()和setxxx()以及edit()方法。

  6. 一旦完全加载到内存, 后续的getXXX()则是直接访问内存

3.读取

  1. 在xml文件全部内加载到内存中之前,读取操作是阻塞的
  2. 在xml文件全部内加载到内存中之后,是直接读取内存中的数据

4.写入

5.优化

  1. sp里面存储特别大的key/value, 有助于减少卡顿/anr
  2. 不要高频地使用apply和commit, 尽可能地批量提交。因为每次提交就是xml文件的全部重写
  3. commit直接在主线程操作, 要注意
  4. 不要使用MODE_MULTI_PROCESS,多线程不应该使用SPI
  5. 高频写操作的key与高频读操作的key可以适当地拆分文件, 由于减少同步锁竞争
  6. 不要一上来就执行getSharedPreferences().edit(),因为getSharedPreferences()是在其他线程进行但是会阻塞.edit()。
  7. 不要连续多次edit(), 应该获取一次获取edit(),然后多次执行putxxx(), 减少内存波动。

参考文章:全面剖析SharedPreferences

上一篇 下一篇

猜你喜欢

热点阅读