2012-12-29 22 views

回答

6

共享首選項存儲在文件夾data/data/your.application.package/shared_prefs/中的xml文件中。該文件被稱爲your.application.package_preferences.xml;

當您檢索共享首選項時,您可以調用Context.getSharedPreferences方法。它創建SharedReferences對象並調用SharedReferences.startLoadFromDisk方法。

如果您打開此方法,您將看到帶有首選項(mFile)的xml文件被解析並且首選項被加載到內存存儲器(map)中。

BufferedInputStream str = new BufferedInputStream(new FileInputStream(mFile), 16*1024); 
map = XmlUtils.readMapXml(str); 

從那時起,您將始終從內存中讀取您的偏好。更確切地來自private Map<String, Object> mMap變量。 此外,應用程序可以調用startReloadIfChangedUnexpectedly方法,如果底層文件已被更改,它將被解析並創建一個新的HashMap。

至於你的問題,有以下幾種情況:

  1. 你在新版本中增加了一個首選項。然後返回指定爲第二個參數的默認值。注意:屬性android:defaultValue沒有使用,所以要注意。

    String v = (String)mMap.get(key); // not found => v = null

    return v != null ? v : defValue; // return defValue

  2. 你在新版本中刪除首選項目。 xml文件和map對象將包含一些冗餘數據,但當用戶下次保存首選項時它將被修復。

  3. 您將首選項的關鍵字更改爲某個未使用的關鍵字。然後將返回默認值。與第1頁相同的結果。

  4. 您刪除一個偏好項(與密鑰pref1_key,例如)和改變另一個項目的鍵,以便它指的是第一項(從pref2_keypref1_key)。然後,第二個首選項將具有第一個項目的值。

  5. 您更改了某個首選項的類型(例如,從boolean到int)。然後它會拋出CastException,因爲這個和類似的代碼:(Integer)mMap.get(key);。但是,您可以將EditTextPreference更改爲ListPreference,因爲它們都具有String類型。

也許有一些更多的測試案例,但到目前爲止,我已經決定了只有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> 
+0

非常感謝您提供詳細的答案。您列出的案例正是我的想法。我認爲在應用程序開發過程中更改首選項結構是一種相當常見的情況,但在Android文檔中找不到解決它的任何問題。也許,我沒有看到正確的文件。 – Hong

+2

@Hong有時在官方文檔中沒有任何信息,這就是爲什麼我使用grepcode網站並自己檢查源代碼。 – vorrtex

2

當應用程序用新的首選項結構更新時,Android如何處理現有的首選項數據?

目前還不清楚「偏好結構」是什麼意思。

你可以認爲SharedPreferences是一個持久的HashMap。您可以在各種按鍵下存儲各種值,並且可以稍後再取回它們。 Android沒有先驗關鍵的知識或將存儲在這些關鍵字下的值的類型,直到您實際存儲某些內容。

我的猜測是,通過「偏好結構」,你的意思是「XML中的首選項屏幕定義」。在這種情況下:

  • 如果添加新的偏好,Android將處理這些正常,就好像喜好一直圍繞所有沿,但用戶從來沒有

  • 設置這些首選項,如果你刪除您以前使用的偏好,舊數據仍然存在,除非您選擇擺脫它,因爲Android無法知道您將永遠不會再使用該數據

  • 如果您重新輸入偏好(即,將邏輯上相同的keyA替換爲key1偏好),Android將會把key1作爲一種全新的偏好,所以你將需要把智慧在你的代碼某處更新SharedPreferences數據反映的主要變化,如果你選擇

沒有SharedPreferencesOpenHelper等效於SQLiteOpenHelper來管理首選項「模式版本」並幫助您遷移數據。如果您願意,您可以創建這樣一個系統,如果您覺得它會幫助您管理頻繁變化的「偏好結構」。

相關問題