应用SharedPreferences在进程之间通信时你会遇到的问题

应用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()将修改后的内容写入到磁盘当中。所以下一次取出的值是正确的。

展开阅读全文

没有更多推荐了,返回首页