对 SharedPreferences 的源码分析 : 提供简易的k v 的存储, 但SharedPreferences 系统机制也存在内存占用,全量写入的问题

时间:2022-02-19 12:20:08

http://www.cnblogs.com/devinzhou/articles/3627107.html

一、        背景 :

 

ShardPreferences 的使用介绍

 

为了提供简易化的键值对的文件存储, android 系统为我们提供了 SharedPreferences 这个玩意.

 

l  我们根据ContextWrapper( 实际上 Activity, Service,Application 都是 ContextWrapper 的子类提供的方法 getSharedPreferences(String name, int mode) 来获取 一个 SharedPreferences 的引用,

 

l  通过 SharedPreferences 的引用 调用 get*() 方法来获取 key 对应的指定类型的 value.

 

l  通过 SharedPreferences 的引用 调用 editor() 返回一个 Editor 对象就可以调用 put*() 存储 新的 键值对或对老的键值对进行修改然后调用 commit()  apply() 完成提交

 

 

二、        SharedPreferences 的局限:

 

提供了文件存储api 非常简单易用轻轻松松搞定键值对的存储但轻便的背后也带来了一些问题.

 

SharedPreferences 的问题:

 

a)         常驻内存 :  SharedPreferences 在被使用的时候会把文件中的全量数据加载到内存中, 只要加载过整个SharedPreferences 文件一直常驻内存且不会被释放.

 

SharedPreferences 在加载完之后会放到 Context 的一个静态的HashMap 对象 sSharedPrefs 中保存且没有接口 把这个 对象从 sSharedPrefs中移除.因此 如果不从 SharedPreferences中移除这些数据这些数据将常驻内存.

                  

 

b)         内容加载 :  SharedPreferences 在被用到的时候加载数据的方式是 :  调用 new Thread() 开启一个线程然后用这个线程去 读取 SharedPreferences 对应的xml文件.

之前的Qzone在启动的时候会尝试打开 30 多个 SharedPreferences .  想象一下  应用启动的时候  30多个要求 磁盘 IO 的线程在运行程序肯定会被拖的比较慢.

 

         

 

c)         数据写入 :   每次SharedPreferences 文件中任何修改都是全量数据写入磁盘因此不建议较大的数据存入到SharedPreferences 文件中也不建议 SharedPreferences文件进行频繁的修改因为每次调用 SharedPreferences  editor()  commit()  apply() 都会触发一次写 磁盘的 IO .

 

d)         提交方式 :   commit() 的方式提交 SharedPreferences 的修改会阻塞当前线程如果 阻塞的是 UI 线程 , 就有可能会造成卡顿建议 android 系统  2.3 以上的 都用 apply() 方式提交SharedPreferences 的修改.

 

 

三、        针对 SharedPreferences的建议

 

1.       一些较大的数据可以考虑自己写 db(sqlite) , 然后  内存中做 cache 控制 IO 操作的频率, , 同时也可以避免 全量的数据被加载到 内存中占用较大内存.

 

2.       整合 SharedPreferences 的文件数量避免过多的 SharedPreferences 文件 引起 创建过多的有 磁盘 IO 操作的线程.

 

è 如果 10 小的 SharedPreferences 文件每个 1kB, 那么读取的时候需要起 10   磁盘 IO 操作的线程进行 10  磁盘 IO 操作.

è 但如果有一个 SharedPreferences 文件 大小为 10 kB, 文件读取时的 buff  16 kB, 则只需要 一个有 磁盘 IO 操作的线程进行 1  磁盘 IO 操作.

 

3.       尽量使用 apply() 代替 commit()  来完成 SharedPreferences 文件的更改的提交.

 

4.       在使用 SharedPreferences 的时候要注意  : SharedPreferences 中存储的数据  一直常驻 内存的.