一、SharedPreferences简介

Android 中的 SharedPreferences(后续简称SP)是轻量级的数据存储方式,能够保存简单的数据类型,比如 String、int、boolean 值等。应用场合主要是数据比较少的配置信息。其内部是以 XML 结构保存在 /data/data/包名/shared_prefs 文件夹下,数据以键值对的形式保存。

使用Preference来存取数据,用到了SP接口和SP的一个内部接口SharedPreferences.Editor,这两个接口在android.content包中。

调用Context.getSharedPreferences(String name,int mode)方法得到SP接口。该方法的第一个参数是文件名称,第二个参数是操作模式。操作模式有三种:MODE_PRIVATE(私有)、MODE_WORLD_READABLE(可读)、MODE_WORLD_WRITEABLE(可写)。

SP提供了获得数据的方法,如getString(String key,String defValue)、getInt(String key,int defValue)等。调用SP的edit()方法返回SharedPreferences.Editor内部接口,该接口中提供了保存数据的方法,如putString(String key,String value),putInt(String key,int value)等,调用该接口的commit()方法可以将数据进行保存。

二、SP性能优化点

SP性能变差的原因有很多。
1、原生API的限制

(1)IO瓶颈
IO瓶颈造成SP性能差是最大的原因,解决了IO瓶颈,80%的性能问题就解决了。
SP的IO瓶颈包括读取数据到内存与数据写入磁盘两部分。
读取数据到内存有两个场景会触发:
  1. SP文件没有被加载到内存时,调用getSharedPreferences方法会初始化文件并读入内存。
  2. 版本低于android_H或使用了MULTI_PROCESS标志时,每次调用getSharedPreferences方法时都会读入。
我们可以优化的便是(2)了。每次加载数据到内存太过影响效率。
H以下版本留存率已经很低了,基本可以忽略。
对于MULTI_PROCESS,可以采用ContentProvider等其他方式,效率更好,而且可避免SP数据丢失的情况。

数据写入磁盘也有两个场景会触发:
  1. Editor的commit方法,每次执行时同步写入磁盘。
  2. Editor的apply方法,每次执行时在单线程池中加入写入磁盘Task,异步写入。
commit和apply的方法区别在于同步写入和异步写入,以及是否需要返回值。
在不需要返回值的情况下,使用apply方法可以极大的提高性能。
同时,多个写入操作可以合并为一个commit/apply,将多个写入操作合并后也能提高IO性能。
(2)锁性能差
SP的get操作,会锁定SharedPreferences对象,互斥其他操作。
SP的put操作,getEditor及commitToMemory会锁定SharedPreferences对象,put操作会锁定Editor对象,写入磁盘更会锁定一个写入锁。
由于锁的缘故,SP操作并发时,耗时会徒增。减少锁耗时,是另一个优化点。
由于读写操作的锁均是针对SP实例对象的,将数据拆分到不同的sp文件中,便是减少锁耗时的直接方案。
降低单文件访问频率,多文件均摊访问,以减少锁耗时。
用开发机进行了简单的性能测试(写入均使用apply,若使用commit则多线程耗时更高):
读写同一文件,10个线程每个读写10次数据:
耗时80-130ms
读写10个文件,每个文件由1个线程读写10次数据:
耗时30-70ms
2、对SP的不当封装也会间接造成数据读写性能差。
由于我们项目采用了插件化,所以对SP的操作涉及到了跨进程访问。
我们采用ContentProvider方案支持跨进程访问,并对所有SP操作均套上了ContentProvider进行访问。
随着项目越来越庞大,通过ContentProvider访问造成的耗时性能也成了问题。
对ContentProvider操作SP测试,耗时是直接操作SP的4倍左右。
所以,最近项目中进行了SP的处理,对于不需要跨进程的SP操作去掉了ContentProvider,尽可能减少无谓耗时。

三、SP优化的建议

1、尽量不要直接调用SharedPreferences进行读写操作。

若直接调用getSharedPreferences(fileName,mode).edit().putString(key,value),则对数据的操作直接耦合了fileName和key,后续想调整file和key会比较困难。
可以考虑封装一下,譬如:
public void saveUserId(){getSharedPreferences(fileName,mode).edit().putString(“user_id”,value);
}
这样做可以直接对数据访问,而与fileName与key解耦,后续拆分与调整时会很方便。

2、将SP作为耗时操作对待,尽量减少无谓的调用。
譬如以下代码,SP读一次即可:
if(sp.getUserId()>0){int id=sp.getUserId();...
}


五、其他程序访问本程序的配置数据方式

       通过SharedPreferences创建的配置文件,不需要指定路径和文件后缀名,读取的时候也是。通常情况下,配置只是提供给本应用程序使用的。在这里我们介绍一个小知识点,即其他程序想使用本应用程序的配置,那应该如何使用SharedPreferences呢?如下:
Context otherAppContext = createPackageContext("com.gary.appdisplaycontrol", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences sharedPreferences = otherAppContext.getSharedPreferences("preferences",Context.MODE_WORLD_READABLE|Context.MODE_MULTI_PROCESS); 
备注:必须要添加Context.MODE_MULTI_PROCESS属性,否则会遇到其他程序读取数据未更新问题。

Android SharedPreferences总结及优化相关推荐

  1. android SharedPreferences的使用优化

    今天,简单讲讲android如何优化使用SharedPreferences保存数据. 之前,我写代码是都是每次缓存一个键值对就commit一次,后来在完成看了看,发现应该是缓存完所有键值对后,再一次性 ...

  2. ym——Android之ListView性能优化

    转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! Android之ListView性能优化 假设有看过我写过的15k面试题的朋友们一定知 ...

  3. 【Android 性能优化】布局渲染优化 ( 过渡绘制 | 背景设置产生的过度绘制 | Android 系统的渲染优化 | 自定义布局渲染优化 )

    文章目录 一. 背景设置产生的过度绘制 二. Android 系统的渲染优化 1. 透明组件数据传递 2. GPU 存储机制 3. Android 7.0 之后的优化机制 三. 自定义布局渲染优化 一 ...

  4. android系统电量优化,基于Android系统网络耗电量优化方法的.pdf

    基于Android系统网络耗电量优化方法的 2012年第10期,第 45卷 通 信 技 术 Vol.45,No.10,2012 总第250期 Communications Technology No. ...

  5. Android:Socket客户端开发,Android 的Socket客户端优化,Android非UI线程修改控件程序崩溃的问题

    一.Android:Socket客户端开发 创建一个工程 我们要做的是按下按键之后,去往服务器 (服务器) 或者我们自己写的服务器 ,给他发送一些预定好的东西 然后打开操作界面 然后修改一下 你要发送 ...

  6. android SharedPreferences数据存储

    android  SharedPreferences数据存储 很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的QQ,用户可以设置是否允许陌生人添加自己为好友.对于软件配置参数的保存 ...

  7. android sharedpre,Android SharedPreferences四种操作模式使用详解_Android_脚本之家

    Android  SharedPreferences详解 获取SharedPreferences的两种方式: 1 调用Context对象的getSharedPreferences()方法 2 调用Ac ...

  8. android sharedpreferences工具类

    今天,简单讲讲如何写一个sharedpreferences的工具类. 很简单,把一些重复的操作封装在工具类里,其他地方调用就可以.在网上搜索了比较多的资料,找到一个比较好的工具类. 参考文章:http ...

  9. android SharedPreferences保存list数据

    今天,简单讲讲如何使用  SharedPreferences保存list数据. 网上找了很多资料,还是觉得这种比较简单.直接上代码: 保存: public static boolean saveA ...

最新文章

  1. 第二篇:智能电网(Smart Grid)中的数据工程与大数据案例分析
  2. 专业的秘密 | 南方医科大学生物信息学专业
  3. github打开出错
  4. Cocos2d-x3.0 不规则Button
  5. netty系列之:netty中各不同种类的channel详解
  6. 出国?上研?工作?回家种田?(二) 专业与上研相关问题
  7. map与unordered_map
  8. 工作308:控制change
  9. CSV Data Set Config设置
  10. cvc-complex-type.2.3: Element 'beans' cannot have character [children]
  11. 音视频开发之旅(41)-天空盒
  12. linux怎么做ppapi工具,如何在Linux上构建PPAPI插件?
  13. yarn启动vue项目
  14. 企业级用户画像: 价格敏感度模型-PSM
  15. html 搜索历史记录,使用cookie实现历史搜索记录功能
  16. WORD邮件合并打印EXCEL数据制作大量奖证、奖状、准考证、成绩单、明信片、信封等个人报表
  17. php人机验证,89.人机验证(一) |《TDD 构建 Laravel 论坛笔记》| Laravel China 社区...
  18. “8421码 5421码 2421码 余3码”区别
  19. MySQL的安装步骤详解
  20. 计算机网络域名解析,域名解析是什么意思?

热门文章

  1. 怎么形容智能冰激凌机器人_有关于形容描写冰激凌的句子及图片
  2. 【转】DICOM图像像素值、灰度值与CT值!!!!!
  3. Azure Table storage 基本用法 -- Azure Storage 之 Table
  4. 一步步编写操作系统 45 用c语言编写内核2
  5. fatal error lnk1120: 1 个无法解析的外部命令_3月1日七牛云存储割韭菜的应对方法...
  6. 算法 - 堆排序(大顶堆、小顶堆)
  7. Python3 爬虫学习笔记 C09【数据储存系列 — 文件储存】
  8. PWN-PRACTICE-BUUCTF-9
  9. 【PAT - 甲级1004】Counting Leaves (30分) (dfs,递归)
  10. 【2019牛客暑期多校训练营(第八场)- G】Gemstones(栈,模拟)