带着问题学习
SharedPreference是线程安全的吗?
SharedPreference的apply和commit有什么区别?
SharedPreference是否会阻塞主线程?
SharedPreference的文件是存储在哪的?
SharedPreference与应用程序之间是一对一的吗?
简介
SharedPreference 是一种以 键值对 形式存储数据的存储方式,在使用的时候,可以指定是否将其共享,最终的 SharedPreference 文件是存储在对应应用的存储区的(具体的是 /data/data/packageName/shared_prefs),也就是说,默认其他应用是无法访问的简单使用
- 获取
SharedPreference实例
- 获取
sharedPreferences的编辑对象
- 利用
editor,存储相关数据
- 把结果提交,也就是写到文件中
源码解析
SharedPreferencesMode
在使用
getSharedPreferences() 时,需要传入两个参数,一个是 filename,也就是存储在本地中的 xml 文件的文件名,而 mode 是指存储的权限,对于第一个参数没什么好说的,所以,来看看 mode 有哪些取值先可以看到有四种取值,其中
MODE_MULTI_PROCESS 的作用是表明该 SharedPreference 文件允许被多个进程进行访问,而一般情况下,当调用了 getSharedPreferences() 方法时,SharedPreference 的对象就会与调用它的应用进程绑定,此时如果有其他应用进程来访问该 SharedPreference 文件,是会报错的,也就是默认情况下,SharedPreference 和调用的进程之间是一对一的关系。查看 getSharedPreferences()
直接点进
getSharedPreferences() 的实现,发现其是调用关系如下:原来是调用了
Context 实现的 getSharedPreferences() 方法,那我们就跟过去看看 Context 中是怎么实现的 getSharedPreferences() :发现
Context 是一个抽象类,而 getSharedPreferences() 也是一个抽象方法,因此查看 Context 的实现类 ContextImpl,下面来看看 ContextImpl 中的实现:到这里,就看明白了
SharedPreferences 的实例是怎么创建以及获取的了,下面来看看 SharedPreferences 真正的实现类 SharedPreferencesImpl 是怎么实现的SharedPreferencesImpl
该类是真正提供
SharedPreferences 实现的类,也就是说,SharedPreferences 的各种操作,都是由该类实现并提供的看完了
SharedPreferencesImpl 构造时的流程,可以知道,SharedPreferencesImpl 在一构造出来的时候,就会启动一个子线程,从磁盘存储中加载相应的 SharedPreferences 文件到内存中那么接下来就来看看
SharedPreferencesImpl 中提供的各种操作方法的实现是怎么样的:get系列方法以getString()方法为例,其他都类似
edit
到了这里,就到了我们在需要修改
SharedPreferences 中值时候需要用到的 Editor 的实现类 EditorImpl 了,接下来就来看看相关的方法是怎么实现的EditorImpl
- 点进源码发现,该类还是
SharedPreferencesImpl的一个内部类,接下来就来看看相关的方法是怎么实现的
put系列方法,以putString()方法为例,其他都类似
在上面的代码中看到,
put 系列的操作,并没有真正把我们的修改写入到相应的文件中,而是保存在内存中,按照我们的使用步骤,在修改完值之后,还要调用 apply 或 commit 方法把最终的修改保存到文件中apply方法
commit方法
从上面
commit 和 apply 的方法实现中,可以看出,两者都调用了 SharedPreferencesImpl.this.enqueueDiskWrite() 方法,来把写入磁盘的任务加入队列,下面来看看 SharedPreferencesImpl.this.enqueueDiskWrite() 的具体实现是什么总结
- 从上面
apply和commit的方法可以看出来,apply是在子线程中等待写入磁盘的任务结束,而commit是在运行线程中等待写入磁盘的任务结束,也就是说apply是异步写入磁盘的,commit是同步写入磁盘的,因此如果写入任务过重的话,commit可能会导致ANR。而且commit方法是有返回值的,而apply没有,这也很好理解,因为很难让异步的方法,返回其运行结果,还不阻塞住线程
- 对于
commit的把数据写进磁盘的操作来说,不一定是只执行在主线程,也有可能是执行在子线程,具体要看其前面的apply是否已经执行完毕
问题回答
SharedPreference是线程安全的吗?- 是的,所有操作都有
syschronized修饰
SharedPreference的apply和commit有什么不同?apply是异步的,是启动子线程来执行把结果写入磁盘的操作commit是同步的,一般是在主线程中执行把结果写入磁盘的操作
SharedPreference是否会阻塞主线程?- 使用
apply就不会,使用commit一般都会,也有特例
SharedPreference的文件是存储在哪的?- 存储在应用的存储区
SharedPreference与应用程序之间是一对一的吗?- 不是,一个应用可以持有多个
SharedPreference,但如果没有特别指定SharedPreference的模式为MODE_MULTI_PROCESS,则一个SharedPreference只能被一个应用进程持有
- Author:CoderWdd
- URL:https://www.wuinsights.top//article/5fe657f1b530
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts