2019独角兽企业重金招聘Python工程师标准>>>

Android开发中经常用到SharedPreference来存储一些配置数据。它的API比较简单,易用。但是在一次简单的bug排查中发现了一个非常有意思的问题。现在就把这个问题和分析结果写下来,仅供参考。

我们的一个模块在SharedPreference中写了一条数据,结果发现重启手机之后,SharedPreference中所有的数据都丢失了。

这个问题很严重,沿着逻辑分支走了几遍,不像是误删除的结果。回过头来仔细看了一下最后一次SharedPreference中写入的数据,才轰然大悟。

<map>
<boolean value="true">
</map>

问题出在:写入数据的key是空,只有value是true。这里有两个问题。第一为什么key为空。第二为什么会导致SharedPreference所有的数据丢失?

第一个问题是产品逻辑的bug。

第二个问题的分析如下:

1)SharedPreference的实现类是android.app.SharedPreferencesImpl。当该类初始化的时候,会从XML文件中把保存的内容加载的内存中。

private void loadFromDiskLocked() {..........Map map = null;FileStatus stat = new FileStatus();if (FileUtils.getFileStatus(mFile.getPath(), stat) && mFile.canRead()) {try {BufferedInputStream str = new BufferedInputStream(new FileInputStream(mFile), 16*1024);map = XmlUtils.readMapXml(str);str.close();} catch (XmlPullParserException e) {Log.w(TAG, "getSharedPreferences", e);} catch (FileNotFoundException e) {Log.w(TAG, "getSharedPreferences", e);} catch (IOException e) {Log.w(TAG, "getSharedPreferences", e);}}mLoaded = true;if (map != null) {mMap = map;mStatTimestamp = stat.mtime;mStatSize = stat.size;} else {mMap = new HashMap<String, Object>();}notifyAll();}

2) XmlUtils.readMapXml(str)中发生了什么事情? 最后追踪到这样一个函数:

public static final HashMap readThisMapXml(XmlPullParser parser, String endTag, String[] name)throws XmlPullParserException, java.io.IOException{HashMap map = new HashMap();int eventType = parser.getEventType();do {if (eventType == parser.START_TAG) {Object val = readThisValueXml(parser, name);if (name[0] != null) {//System.out.println("Adding to map: " + name + " -> " + val);map.put(name[0], val);} else {throw new XmlPullParserException("Map value without name attribute: " + parser.getName());}} else if (eventType == parser.END_TAG) {if (parser.getName().equals(endTag)) {return map;}throw new XmlPullParserException("Expected " + endTag + " end tag at: " + parser.getName());}eventType = parser.next();} while (eventType != parser.END_DOCUMENT);throw new XmlPullParserException("Document ended before " + endTag + " end tag");}

看到这里就清楚了,因为最开始的那个XML文件中boolean只有value,没有name,导致name[0] == null,抛出异常。结果整个返回的HashMap是空。

Google在Issue 63463中fix了这个问题:

http://code.google.com/p/android/issues/detail?id=63463

简单的讲就是:SharedPreference在读/写的时候支持null key,而不再是抛异常了。

相关的讨论在这里:

https://groups.google.com/forum/#!topic/android-developers/JpDzZtbrjfA

转载于:https://my.oschina.net/u/145002/blog/291907

危险的SharedPreference操作相关推荐

  1. 一种面向危险环境远程操作的仿人随动机器人

    摘要: 为代替专业人员在高危环境中工作,开展了一种面向危险环境远程操作的仿人随动机器人研究.首先,基于人体上肢生物学特性,设计了从端仿人随动机器人并利用蒙特卡洛法对其理论运动空间进行分析.其次,依据人 ...

  2. C#中利用委托实现多线程跨线程操作

    在使用VS2005的时候,如果你从非创建这个控件的线程中访问这个控件或者操作这个控件的话就会抛出这个异常.这是微软为了保证线程安全以及提高代码的效率所做的改进,但是也给大家带来很多不便. 其实解决这个 ...

  3. C#多线程操作界面控件的解决方案

    C#中利用委托实现多线程跨线程操作 - 张小鱼 2010-10-22 08:38 在使用VS2005的时候,如果你从非创建这个控件的线程中访问这个控件或者操作这个控件的话就会抛出这个异常.这是微软为了 ...

  4. 显卡刷bios变砖怎么办--关于矿卡,一些惊呆我的骚操作

    趁着双11的热度,也体验了一把什么叫做矿卡? 选择的是三战老兵,矿卡重灾区的RX580系列,价格不到300的XFX RX580 8G 2304满血版,商家是这么描述的,估且信着吧,商家还很好心的提示, ...

  5. MySQL - 对数据表进行“增删查改”的基础操作 - 细节狂魔

    文章目录 前文知识点回顾 正文 :对数据表进行"增删查改"操作 新增操作 - insert 关键字 查找语句(基础操作) - select关键字 - 重点!!!!!!!! 1.最基 ...

  6. php写接口curd,接口实战(数据库的CURD操作)

    interface iCurd{ //    增加数据 public function create($data); //读取数据 public function read(); //更新数据 pub ...

  7. 教你如何快速关闭危险端口

    Antian365 by 终隐 一.前言 前段时间"永恒之蓝"勒索病毒肆掠全球.不法分子将泄露的NSA黑客武器库中"永恒之蓝"攻击程序改造成了蠕虫病毒用于网络攻 ...

  8. linux中高危端口,端口随意开很危险 常见端口解析

    端口随意开很危险 常见端口解析 [日期:2007-07-14] 来源:Linux公社 作者:Linuxidc [字体:大 中 小] 113端口:113端口主要用于Windows的"Authe ...

  9. linux nfs acl 特定ip,技术|RHCSA 系列(七): 使用 ACL(访问控制列表) 和挂载 Samba/NFS 共享...

    在上一篇文章(RHCSA 系列(六))中,我们解释了如何使用 parted 和 ssm 来设置和配置本地系统存储. RHCSA 系列: 配置 ACL 及挂载 NFS/Samba 共享 – Part 7 ...

最新文章

  1. YYH的苍天大竹(NOIP模拟赛Round 6)
  2. supervisor python_使用supervisor运行python脚本
  3. Bagging(bootstrap aggregating)
  4. Asp.Net就业课之三验证控件
  5. 通过从备份中排除这些文件夹来节省Time Machine驱动器上的空间
  6. 【计蒜客 - 蓝桥训练】修建公路(贪心,或运算,dp)
  7. linux重定向命令是干嘛的,Linux系统下重定向命令应用及其语法有什么?
  8. java反射 Method
  9. python+selenium+unittest测试框架1-unittest单元测试框架和断言
  10. ScreenFlow for mac 录制视频的工具
  11. 一個簡單的不能再簡單的技巧。。。好吧。。css恩。。定位於window 給 IE6+
  12. worddayi计算机考试题,期末试卷
  13. 基于python的图书管理系统设计与实现论文_基于JAVA的图书馆管理系统设计[毕业论文_].doc...
  14. Matplotlib调整字体大小
  15. clearcase 与 git的区别
  16. linux 内核 触摸屏,向内核里面添加触摸屏驱动(方法适合其他设备)
  17. Python3,4行代码给图片加美颜,拍照再也不需要开美颜滤镜了。
  18. 程序员与颈椎病(三):颈椎病终极解决办法
  19. Millet谷仓:人人受益的电商
  20. 英语口语234之每日十句口语

热门文章

  1. Eclipse 编译项目
  2. CSS3给页面打标签
  3. VS2010 没有C#或者其他模板怎么办,不用重装
  4. HLG 数字去重和排序II【二叉排序树】
  5. windows 开始命令集
  6. php+求二分查找递归算法,PHP二分查找(递归和循环)
  7. 插入排序(Insert Sort)
  8. 大数据分析哪些错误需避免
  9. 【运维】PowerShell编程 目录文件相关方法的封装与案例详解
  10. python与Labview进行数据通信(UDP)