文档章节

Android SharedPreferences 源码分析

unibigbear
 unibigbear
发布于 2016/05/10 10:11
字数 1383
阅读 16
收藏 0

SharedPreferences(以下使用SP简称)在Android中作为一种使用简单的数据存储形式被广泛用来存储一些不需要做数据库操作的数据,比如用户配置项等。本文将从源码入手分析其实现,并据此提出一些使用中需要注意的事项。

分析

代码口

        SP是一个interface,首先我们得找到它的具体实现。在SP的使用中,我们通过getSharedPreferences()获取SP实例如下:

而getSharedPreferences 是Context接口中的方法。稍微对Android SDK    源码有所了解的朋友都知道,Context的主要实现类——ContextImpl。在该类

中,我们可以找到getSharedPreferences方法的具体实现,

  从以上代码我们可以获取到以下几点信息:

  1. SP的实现类为SharedPreferencesImpl。

  2. 在ContextImpl中维护了一个从包名到SP字典的字典。

  3. 传null作为SP的name是被允许的,它会生成一个以null.xml为名的文件。

  4. 当sdk version 在3.0以下时支持“MODE_MULTI_PROCESS”模式,在该模式下,每次获取SP实例时,判断文件是否被改动,在被改动的情况下重新从文件加载数据,以实现多进程数据同步。但是后来发现即使如此在某些情况下还是不能保证多进程数据一致性,因此就被deprecated了,在3.0以上即使设置了MODE_MULTI_PROCESS也没有任何作用。

SharedPreferencesImpl

       接下来是让我们移步SharedPreferencesImpl,看一下sp的具体实现。

成员变量

初始化过程

       以下是SPImpl的构造方法。它初始化了成员变量,并调用startLoadFromDisk()用来初始化数据。

 在startLoadFromDisk中启用了一个线程调用了真正的读文件加载数据方法 —— loadFromDiskLocked。该方法读取文件并使用XmlUtils类对读取的数据进行解析。

读取数据

       对于SP的使用,我们用的最多的可能就是取数据,以取String类型数据为例,getString方法首先取得SharedPreferencesImpl.this对象锁,然后同步等待从文件加载数据完成,最后再返回数据。因此这里会有一定的延迟。如果是在UI线程执行SP的取数据操作,可能会对UI流畅度方面造成一定的影响,不过在实践中我们认为这可以忽略不计。

存数据

      看完读取数据,接下来再介绍下写数据。对于SP的写操作主要是通过Editor接口来完成的,SPImpl中的内部类EditorImpl是Editor的具体实现。

       所有的put打头的方法只是将需要修改的键值保存到mModified这个字典中。

 所以重头戏是我们经常使用的commit和apply方法。这两个方法都是首先修改内存中缓存的mMap的值,然后将数据写到磁盘中。它们的主要区别是commit会等待写入磁盘后再返回,而apply则在调用写磁盘操作后就直接返回了,但是这时候可能磁盘中数据还没有被修改。

    以上两个方法都调用了commitToMemory。该方法主要根据mModified和是否被clear修改mMap的值,然后返回写磁盘需要的一些相关值。

写磁盘

       最后一块比较重要的就是SP的写磁盘操作。之前介绍的apply和commit都调用了enqueueDiskWrite()方法。

       以下为其具体实现。writeToDiskRunnable中调用writeToFile写文件。如果参数中的postWriteRunable为null,则该Runnable会被同步执行,而如果不为null,则会将该Runnable放入线程池中异步执行。在这里也验证了之前提到的commit和apply的区别。

Mode相关

       下面我们分析一下获取SP实例时的第二个参数 mode,上文我们已经提到了一个被废弃的mode——MODE_MULTI_PROCESS。在SPImpl中在writeToFile方法中用到了该参数。再看setFilePermissionsFromMode方法,根据MODE参数设置文件的读写权限,而从中我们可以看出能够造成影响的两个MODE分别为MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE。而这两个值在API17之后被Deprecated,所以不建议使用,如果需要多App共享数据,建议使用ContentProvider。

总结

        以上为对SP代码的分析,根据以上分析,提出以下几个在使用SP中需要注意的点。

1、MODE_MULTI_PROCESS 无法保证多进程数据一致性,在3.0以上已经没有任何作用。

2、SP从初始化到读取到数据存在一定延迟,因为需要到文件中读取数据,因此可能会对UI线程流畅度造成一定影响。

3、commit在将数据写入磁盘后才会返回,而apply则直接返回但无法保证写磁盘已经完成,只能保证内存中数据的正确性。

4、MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE已经被废弃,不建议使用,如果需要多App共享数据,建议使用ContentProvider,Github上有一个对ContentProvider的封装Tray,用起来和SP差不多,还是蛮不错的。

(全文链接:http://mp.weixin.qq.com/s?__biz=MzI5ODI3NzY2MA==&mid=100000117&idx=4&sn=3539fdcbca4610198b72da760abdc8fa#rd)

欢迎大家一起交流。

扫描以下二维码,获取更多更精美文章!

关注我们微信订阅号( uniguytech100) 与服务号(uniguytech),获取更多更精美文章!

也欢迎加入【大家技术网讨论QQ群】,群号码:256175955,请备注你个人的介绍!让我们一起聊聊it的那些事!

© 著作权归作者所有

共有 人打赏支持
unibigbear
粉丝 1
博文 70
码字总数 5874
作品 0
闵行
私信 提问
android基础知识07:SharedPreferences和PreferenceActivity

本文主要介绍SharedPreferences和PreferenceActivity的基础知识和用法。 主要资料来源于网络,包括但不限于: 《Android之PreferenceActivity》 《在Android中Preferences数据存储的使用》 ...

迷途d书童
2012/03/23
8.5K
1
Android_6.数据存储2_SharedPreferences存储

本文是以Android Studio为开发工具,<> 为学习指导书籍的学习记录 6.3 SharedPreferences存储 1、不同于文件的存储方式,SharedPreferences是使用“==键值对==“的方式来存储数据的。即、当你...

橄榄工作室
2018/05/24
0
0
【android学习之九】——数据存储1:SharedPreferences,Files,网络

声明:学习的书籍《Android应用开发揭秘》,这里记录学习该书籍的日志,引用的相关代码与总结描述,没有商业的用途,完全是自我学习的一个记录,刚刚学习不可避免会出现很多问题,若是有错误...

晨曦之光
2012/03/08
1K
1
Android之PreferenceActivity

看到很多书中都没有对PreferenceActivity做介绍,而我在看Android Samples时无意中看见了,所以就稍微总结一下,也方便日后查找。 PerferenceActivity是什么,看下面的截图: 好了,我们看到...

晨曦之光
2012/03/05
356
0
使用AES加密进行Android的SharedPreferences存储

1.概述 SharedPreferences是Android提供用来存储一些简单配置信息的机制,其以KEY-VALUE对的方式进行存储,以便我们可以方便进行读取和存储。主要可以用来存储应用程序的欢迎语、常量参数或登...

尼莫
2013/01/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

SpringBoot2.x配置Cors跨域

SpringBoot2.x配置Cors跨域 1 跨域的理解 跨域是指:浏览器A从服务器B获取的静态资源,包括Html、Css、Js,然后在Js中通过Ajax访问C服务器的静态资源或请求。即:浏览器A从B服务器拿的资源,...

水木星辰
19分钟前
1
0
一文搞懂TCP与UDP的区别

**摘要:**计算机网络基础 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有。 引言 网络协议是每个前端工程师都必须要掌握的知识,TCP/IP 中有两个具有代表性的传输层协议,分别是 TC...

Fundebug
21分钟前
2
0
Hanlp1.7版本的新增功能一览

Hanlp1.7版本在去年下半年的时候就随大快的DKH1.6版本同时发布了,截至目前1.7大版本也更新到了1.7.1了。本篇分别就1.7.0和1.7.1中新增的功能做一个简单的汇总介绍。 HanLP 是由一系列模型与...

左手的倒影
28分钟前
1
0
Linux之PAM可动态加载的认证模块

在Linux中执行有些程序时,这些程序在执行前首先要对启动它的用户进行认证,符合一定的要求之后才允许执行,例如login, su等。在Linux中进行身份或是状态的验证程序是由PAM来进行的,PAM(P...

城市之雾
29分钟前
1
0
程序员接私活那些坑

前言 最近有很多人问我私活怎么样?有什么坑,我之前也是接了几个私活,当然也有稳定的收入。我们也来分享一下。前几天发现了一个帖子很不错,我们来分享一下 注:本文转自 : http://blog.cs...

终端研发部
36分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部