应用SharedPreferences在进程之间通信时你会遇到的问题
2017-05-17 11:52
281 查看
应用SharedPreferences在进程之间通信时你会遇到的问题
出现这样一个问题:先启动主线程并获取SharedPreferences对象,然后对值进行修改,然后再启动其它进程并获取SharedPreferences对象,能够获取修改后的值,但此时如果对此值进行修改,均不能对其他进程产生作用。必须等到进程重启或者app重启才能与其他进程进行数据同步。
原因:只有在创建SharedPreferences对象的时候才会从磁盘中国进行读取,读取完以后值保存在内存(HashMap)当中,下次获取SharedPreferences对象优先从缓存当中获取,所以在当前进程修改了SharedPreferences的值,其他进程的SharedPreferences对象的值并不会改变。只有把当前另外的进程关闭(如:关闭手机、或杀死该app重新进入),再次创建进程时才会重新从磁盘中再次读取文件。
源码分析:通常我们获取SharedPreferences都是通过Context中的getSharedPreference方法来获取SharedPreferences对象,在Context中,getSharedPreference方法是一个抽象方法,没有具体实现。我们知道Context的实现类是ContextImpl,所以直接找到ContextImpl的getSharedPreference方法。可以看到,这里将SharedPreferences的实例对象SharedPreferencesImpl的先通过Map缓存起来,以后每次获取如果内存已经存在,那么直接返回,如果不存在才会重新创建。
那么为什么在同一个进程SharedPreferences应用又没有问题呢?
这是由于Editor 的实现类EditorImpl,但我们修改完SharedPreferences对象之后都会调用commit(直接当钱线程执行)或者apply方法(将当前任务加到线程池中,后台执行)才会执行保存,在源码中可以看到无论调用哪一个方法都会调用commitToMemory()和enqueueDiskWrite方法。commitToMemory()方法就是将值提交到内存当中。enqueueDiskWrite()将修改后的内容写入到磁盘当中。所以下一次取出的值是正确的。
出现这样一个问题:先启动主线程并获取SharedPreferences对象,然后对值进行修改,然后再启动其它进程并获取SharedPreferences对象,能够获取修改后的值,但此时如果对此值进行修改,均不能对其他进程产生作用。必须等到进程重启或者app重启才能与其他进程进行数据同步。
原因:只有在创建SharedPreferences对象的时候才会从磁盘中国进行读取,读取完以后值保存在内存(HashMap)当中,下次获取SharedPreferences对象优先从缓存当中获取,所以在当前进程修改了SharedPreferences的值,其他进程的SharedPreferences对象的值并不会改变。只有把当前另外的进程关闭(如:关闭手机、或杀死该app重新进入),再次创建进程时才会重新从磁盘中再次读取文件。
源码分析:通常我们获取SharedPreferences都是通过Context中的getSharedPreference方法来获取SharedPreferences对象,在Context中,getSharedPreference方法是一个抽象方法,没有具体实现。我们知道Context的实现类是ContextImpl,所以直接找到ContextImpl的getSharedPreference方法。可以看到,这里将SharedPreferences的实例对象SharedPreferencesImpl的先通过Map缓存起来,以后每次获取如果内存已经存在,那么直接返回,如果不存在才会重新创建。
那么为什么在同一个进程SharedPreferences应用又没有问题呢?
这是由于Editor 的实现类EditorImpl,但我们修改完SharedPreferences对象之后都会调用commit(直接当钱线程执行)或者apply方法(将当前任务加到线程池中,后台执行)才会执行保存,在源码中可以看到无论调用哪一个方法都会调用commitToMemory()和enqueueDiskWrite方法。commitToMemory()方法就是将值提交到内存当中。enqueueDiskWrite()将修改后的内容写入到磁盘当中。所以下一次取出的值是正确的。
相关文章推荐
- 应用管道实现父子进程之间的通信
- 应用管道实现父子进程之间的通信
- 《unix网络编程 卷2 进程间的通信》中遇到的代码问题(ubuntu)
- android 跨应用进程之间的通信之AIDL
- iphone守护进程和前台进程之间的通信-前台应用发信息给后台的守护进程
- Operating System-进程/线程内部通信-信号量、PV操作的实现和应用(解决哲学家进餐和生产者消费者问题)
- iPhone开发之—守护进程和前台进程之间的通信-前台应用发信息给后台的守护进程
- eVC编程遇到的各种问题之——进程之间的通讯
- iphone守护进程和前台进程之间的通信-前台应用发信息给后台的守护进程
- hadoop2.6.2集群环境搭建在经过几天的环境搭建,终于搭建成功,其中对于hadoop的具体设置倒是没有碰到很多问题,反而在hadoop各节点之间的通信遇到了问题,而且还反复了很多遍,光虚拟机就重
- 面试遇到的问题 进程和线程以及通信方式
- Lock与Condition应用(三个线程之间通信问题)
- android messager跨应用进程之pacelable遇到问题解决方案汇总
- Operating System-进程/线程内部通信-信号量、PV操作的实现和应用(解决哲学家进餐和生产者消费者问题)
- iphone守护进程和前台进程之间的通信-前台应用发信息给后台的守护进程
- iPhone开发之—守护进程和前台进程之间的通信-前台应用发信息给后台的守护进程
- iphone守护进程和前台进程之间的通信-前台应用发信息给后台的守护进程
- 笔试、面试中遇到的进程通信的问题
- linux运行进程通信遇到问题及解决方法
- 两个进程之间通信