例如,如果添加或删除了几个偏好项,当应用程序更新为新的偏好结构时,Android如何处理现有的偏好数据?
我为这个初级问题感到抱歉,但我的努力搜索和阅读无法找到答案。
共享首选项存储在data/data/your.application.package/shared_prefs/
文件夹下的xml文件中。该文件名为your.application.package_preferences.xml
;
检索共享首选项时,调用Context。getSharedPreferences方法。它创建SharedReferences
对象并调用sharepreferences。startLoadFromDisk方法。
如果您打开这个方法,您将看到具有首选项(mFile
)的xml文件被解析,并且首选项被加载到内存存储(map
)中。
BufferedInputStream str = new BufferedInputStream(new FileInputStream(mFile), 16*1024);
map = XmlUtils.readMapXml(str);
从那时起,你将总是从记忆中读取你的偏好。更确切地说,可以从private Map<String, Object> mMap
变量中找到。应用程序还可以调用startreloadifchangedunexpected方法,如果底层文件已经更改,它将被解析并创建一个新的HashMap。
关于你的问题,有以下几种情况:
您在新版本中添加了一个首选项。然后将返回作为第二个参数指定的默认值。注意:android:defaultValue属性没有被使用,所以要注意。
String v = (String)mMap.get(key); // not found => v = null
return v != null ? v : defValue; // return defValue
你在新版本中删除了一个首选项。xml文件和
map
对象将包含一些冗余数据,但它将在用户下次保存首选项时修复。您将首选项的键更改为未使用的键。然后返回默认值。结果与p.1相同
您删除了一个首选项(例如,使用键
pref1_key
)并更改了另一个项的键,以便它引用第一个项(从pref2_key
到pref1_key
)。然后,第二个首选项将具有第一个项的值。- 您更改了一个首选项的类型(例如,从布尔型到整型)。然后它将抛出CastException,因为这个和类似的代码:
(Integer)mMap.get(key);
。但是你可以改变,例如,EditTextPreference到ListPreference,因为他们都有字符串类型。
也许还有更多的测试用例,但到目前为止我只编了5个。
这里还有一个带有ListPreference, EditTextPreference和CheckBoxPreference的首选项文件的例子:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="pref_theme_key">THEME_LIGHT</string>
<string name="pref_homepage_key">test</string>
<boolean name="pref_display_name_key" value="true" />
</map>
Android如何处理现有的偏好数据,当应用程序与新的偏好结构更新?
我不清楚你所说的"偏好结构"是什么意思。
你可以认为SharedPreferences
是一个持久的HashMap
。你在不同的键下存储不同的值,你可以稍后取回它们。Android没有先验的知识的键或值的类型将存储在这些键,直到你实际存储的东西。
我猜"首选项结构"指的是"XML中的首选项屏幕定义"。在这种情况下:
-
如果你添加新的首选项,Android将正常处理这些,就好像这些首选项一直存在,但用户之前从未设置过这些首选项
-
如果你删除了你以前使用过的首选项,旧的数据仍然存在,除非你选择摆脱它,因为Android无法知道你永远不会再使用这些数据
-
如果你重新键入一个首选项(即,用
key1
替换keyA
逻辑上是相同的首选项),Android将把key1
作为一个全新的首选项,所以你将需要在你的代码中的某个地方更新你的SharedPreferences
数据来反映键的变化,如果你这样选择
没有SharedPreferencesOpenHelper
相当于SQLiteOpenHelper
来管理首选"模式版本"并帮助您迁移数据。如果您愿意,如果您觉得这样可以帮助您管理频繁变化的"偏好结构",那么欢迎您创建这样一个系统。