成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

了解Android API中的SharedPreferences

移動(dòng)開(kāi)發(fā) Android
在Android的開(kāi)發(fā)過(guò)程中,會(huì)在使用的API中見(jiàn)到很多名字中帶有Preference的類(lèi)和接口,此篇文章就來(lái)介紹一下這些“*Prefere*”的功能和用途。

[[181260]]

Preference翻譯為偏好,但實(shí)際上它可以算是Setting(設(shè)置)的別名。兩種叫法給人的差異在于針對(duì)的對(duì)象不同:設(shè)置更傾向于設(shè)備的屬性,修改設(shè)置便是改變?cè)O(shè)備的功能;偏好則傾向于用戶(hù)的性格,用戶(hù)基于其個(gè)人的偏好來(lái)來(lái)形成設(shè)備的差異化。但是總體而言,它們是一致的,都是通過(guò)用戶(hù)的需求改變?cè)O(shè)備的體驗(yàn)。

在Android的開(kāi)發(fā)過(guò)程中,會(huì)在使用的API中見(jiàn)到很多名字中帶有Preference的類(lèi)和接口,此篇文章就來(lái)介紹一下這些“*Prefere*”的功能和用途。

在Android提供API中,帶有Preference的其實(shí)主要分為兩類(lèi):一類(lèi)是android.content包下的SharedPreferences,另一類(lèi)則是android.preference包下的Preference。它們分別實(shí)現(xiàn)不同功能,卻又相互聯(lián)系合作完成對(duì)Android程序的控制。

SharedPreferences簡(jiǎn)介

SharedPreferences是以復(fù)數(shù)形式存在,因?yàn)樵贏ndroid中它是用來(lái)存儲(chǔ)鍵值對(duì)(Key-Value Pair)數(shù)據(jù)的集合。API中包含了多個(gè)方法來(lái)方面讀取相應(yīng)類(lèi)型的數(shù)據(jù):

  1. String getString(String key, String defValue); 
  2. Set<String> getStringSet(String keySet<String> defValues); 
  3. int getInt(String keyint defValue); 
  4. long getLong(String key, long defValue); 
  5. float getFloat(String keyfloat defValue); 
  6. boolean getBoolean(String key, boolean defValue);  

這也表明SharedPreferences所能存儲(chǔ)的類(lèi)型被限定在了String、int、long、float、boolean這些基礎(chǔ)數(shù)據(jù)類(lèi)中,唯一的集合類(lèi)型也只是Set,而它看起來(lái)更像是用來(lái)作為不能有重復(fù)數(shù)據(jù)的數(shù)組。

還可以單純檢查是否包換指定的主鍵,或者干脆將所有的鍵值對(duì)的Map獲取出來(lái):

  1. boolean contains(String key);     
  2. Map<String, ?> getAll();  

Android系統(tǒng)的工程師在設(shè)計(jì)SharedPreferences的時(shí)候,把讀取的功能放在了SharedPreferences上,而把寫(xiě)回的功能實(shí)現(xiàn)在了其內(nèi)嵌的Editor類(lèi)上,通過(guò)調(diào)用edit()方法來(lái)獲得一個(gè)寫(xiě)入器。這樣就很容易實(shí)現(xiàn)一個(gè)只讀的對(duì)象,只要返回一個(gè)空指針或非可用的Editor對(duì)象就可以了。 

  1. Editor putString(String key, String value); 
  2. Editor putStringSet(String keySet<String> values); 
  3. Editor putInt(String keyint value); 
  4. Editor putLong(String key, long value); 
  5. Editor putFloat(String keyfloat value); 
  6. Editor putBoolean(String key, boolean value); 
  7. Editor remove(String key);  

SharedPreferences還有一個(gè)內(nèi)嵌接口OnSharedPreferenceChangeListener,實(shí)現(xiàn)它唯一的方法onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)并通過(guò)以下方法添加在SharedPreferences對(duì)象上就可以監(jiān)聽(tīng)其上鍵值對(duì)的增加、刪除和修改:

  1. void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener); 
  2. void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener);  

SharedPreferences的在Android系統(tǒng)中的實(shí)現(xiàn)

SharedPreferences和內(nèi)嵌的Editor其實(shí)都只是接口定義而已,并沒(méi)有實(shí)現(xiàn)任何方法。它只是用來(lái)制定了一個(gè)存儲(chǔ)鍵值對(duì)的協(xié)議,具體的實(shí)現(xiàn)方式和存儲(chǔ)形式可以是任意的。在Android系統(tǒng)中,它默認(rèn)以XML格式的文件來(lái)存儲(chǔ)這些數(shù)據(jù),實(shí)現(xiàn)的類(lèi)則是SharedPreferencesImpl。

下邊就是所保存的XML文件的基本格式,它以數(shù)據(jù)類(lèi)型作為XML元素的標(biāo)簽,主鍵(key)是標(biāo)簽name屬性的值,而主鍵對(duì)應(yīng)的值則作為value屬性的值。但如果是String類(lèi)型則作為標(biāo)簽下的content,這樣就不用轉(zhuǎn)義引號(hào)也能更好的處理?yè)Q行。另外對(duì)于null值存儲(chǔ)的結(jié)構(gòu)也比較特殊,它以null為標(biāo)簽,只有一個(gè)name屬性,沒(méi)有其他內(nèi)容。 

  1. <?xml version='1.0' encoding='utf-8' standalone='yes' ?> 
  2. <map> 
  3.     <string name="Name">Ider</string> 
  4.     <boolean name="Android" value="true" /> 
  5.     <set name="Subsites"
  6.         <string>code.iderzheng.com</string> 
  7.         <string>blog.iderzheng.com</string> 
  8.         <string>manual.iderzheng.com</string> 
  9.     </set
  10.     <int name="VersionCode" value="21" /> 
  11.     <long name="VersionNumber" value="1355" /> 
  12.     <float name="Version" value="5.0" /> 
  13.     <null name="Null" /> 
  14. </map>  

Android系統(tǒng)會(huì)把該XML文件存儲(chǔ)在/data/data/(packagename)/shared_prefs/下,每一個(gè)XML文件就對(duì)應(yīng)一個(gè)SharedPreferences對(duì)象(實(shí)際是SharedPreferencesImpl對(duì)象)。但是SharedPreferences是接口不能用來(lái)實(shí)例化對(duì)象,而SharedPreferencesImpl是系統(tǒng)隱藏類(lèi),不能被直接訪問(wèn)使用,其構(gòu)造函數(shù)也只是包可見(jiàn)。所以不能通過(guò)new來(lái)構(gòu)建一個(gè)SharedPreferences,必須通過(guò)Context提供的getSharedPreferences(String, int)來(lái)獲得實(shí)例。

該方法的***個(gè)參數(shù)是指定XML文件名(不包含“.xml”后綴)的字符串,方法會(huì)去讀取出對(duì)應(yīng)的文件,創(chuàng)建一個(gè)SharedPreferences對(duì)象。第二個(gè)參數(shù)指定文件的訪問(wèn)權(quán)限,共有4中可選模式,從API 17開(kāi)始基于安全的考慮,MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE已經(jīng)被廢棄使用,只有MODE_PRIVATE和MODE_MULTI_PROCESS可使用,一般情況下指定MODE_PRIVATE即可。

對(duì)于從SharedPreferences中讀取指定主鍵的值是十分快的,因?yàn)樗写嬖赬ML的鍵值對(duì)信息全都被讀取被存儲(chǔ)在了SharedPreferences對(duì)象中的Map成員變量里,所以讀取都是基于內(nèi)存訪問(wèn)。使用Editor寫(xiě)回到文件是避不開(kāi)IO操作的,所以使用commit()提交修改還是會(huì)花費(fèi)一些時(shí)間。考慮到這點(diǎn),Android在API 9里引進(jìn)了apply()方法來(lái)異步地將修改后的內(nèi)容寫(xiě)回到文件,當(dāng)然在寫(xiě)回前也會(huì)先更新內(nèi)存中的鍵值對(duì)信息保證讀取到的時(shí)***的內(nèi)容。

既然寫(xiě)回可以是異步的,那么多次調(diào)用getSharedPreferences(String, int)獲得多個(gè)SharedPreferences賦值給不同的變量,假如一個(gè)變量做了修改,其他的對(duì)象不是會(huì)出現(xiàn)內(nèi)容不一致的情況。其實(shí)這種情況并不會(huì)出現(xiàn),因?yàn)樗袆?chuàng)建出來(lái)的SharedPreferences都被存儲(chǔ)在ContextImp的一個(gè)靜態(tài)成員變量中:

  1. /** 
  2. * Map from package nameto preference nameto cached preferences. 
  3. */ 
  4. private static ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>> sSharedPrefs;  

這是一個(gè)從程序的Package名字到XML文件名再到SharedPreferences對(duì)象的二級(jí)Map。所以每次調(diào)用getSharedPreferences(String, int)得到的對(duì)象其實(shí)都是同一個(gè)實(shí)例,修改操作也都就作用在同一段內(nèi)存中保證了所有訪問(wèn)的一致性。apply()方法也會(huì)自動(dòng)將所有修改排入隊(duì)列一一寫(xiě)回文件從而不會(huì)因?yàn)轫樞虻腻e(cuò)誤而造成意料之外的錯(cuò)誤覆蓋。所以因?yàn)檫@個(gè)緩存機(jī)制的存在,多次調(diào)用getSharedPreferences(String, int)是非常效率的。而寫(xiě)回時(shí)則推薦使用apply()實(shí)現(xiàn)異步操作,而不要用commit()阻礙主線程。

SharedPreferences的使用和示例

一般而言SharedPreferences的名字和主鍵名都是固定的,所以可以定義一些final的字符串變量來(lái)保存這些名字,在讀取和寫(xiě)回時(shí)都使用這些常熟變量。對(duì)于之前展示的XML對(duì)應(yīng)的代碼就如下邊所示: 

  1. private static final String IDER_PREFERENCE = "ider-preference"
  2. private static final String IDER_PREFERENCE_KEY_NAME = "Name"
  3. private static final String IDER_PREFERENCE_KEY_SUBSITES = "Subsites"
  4. private static final String IDER_PREFERENCE_KEY_IS_ANDROID = "Android"
  5. private static final String IDER_PREFERENCE_KEY_VERSION = "Version"
  6. private static final String IDER_PREFERENCE_KEY_VERSION_CODE = "VersionCode"
  7. private static final String IDER_PREFERENCE_KEY_VERSION_NUMBER = "VersionNumber"
  8. private static final String IDER_PREFERENCE_KEY_NULL = "Null"
  9. public void write(Context context) { 
  10.     final SharedPreferences spref = context.getSharedPreferences(IDER_PREFERENCE, MODE_PRIVATE); 
  11.     HashSet<String> strs = new HashSet<String>(); 
  12.     strs.add("blog.iderzheng.com"); 
  13.     strs.add("code.iderzheng.com"); 
  14.     strs.add("manual.iderzheng.com"); 
  15.     SharedPreferences.Editor editor = spref.edit(); 
  16.     editor.putString(IDER_PREFERENCE_KEY_NAME, "Ider"); 
  17.     editor.putStringSet(IDER_PREFERENCE_KEY_SUBSITES, strs); 
  18.     editor.putBoolean(IDER_PREFERENCE_KEY_IS_ANDROID, true); 
  19.     editor.putFloat(IDER_PREFERENCE_KEY_VERSION, 5.0f); 
  20.     editor.putInt(IDER_PREFERENCE_KEY_VERSION_CODE, 21); 
  21.     editor.putLong(IDER_PREFERENCE_KEY_VERSION_NUMBER, 1355); 
  22.     editor.putString(IDER_PREFERENCE_KEY_NULL, null); 
  23.     editor.apply(); 
  24. public void read(Context context) { 
  25.     final SharedPreferences spref = context.getSharedPreferences(IDER_PREFERENCE, MODE_PRIVATE); 
  26.     String name = spref.getString(IDER_PREFERENCE_KEY_NAME, ""); 
  27.     Set<String> strs = spref.getStringSet(IDER_PREFERENCE_KEY_SUBSITES, null); 
  28.     boolean isAndroid = spref.getBoolean(IDER_PREFERENCE_KEY_IS_ANDROID, false); 
  29.     float version = spref.getFloat(IDER_PREFERENCE_KEY_VERSION, 0); 
  30.     int versionCode = spref.getInt(IDER_PREFERENCE_KEY_VERSION_CODE, 0); 
  31.     long versionNumber = spref.getLong(IDER_PREFERENCE_KEY_VERSION_NUMBER, 0); 
  32.     boolean hasKey = spref.contains(IDER_PREFERENCE_KEY_NULL); 
  33.  

既然SharedPreferences的名字是可以任意給定的,所以對(duì)于SharedPreferences的使用就可以有非常的針對(duì)性創(chuàng)建不同的文件來(lái)存儲(chǔ)不同的內(nèi)容。比如可以以不同用戶(hù)為名存放他們的偏好信息,可以根據(jù)不同界面保存布局信息、已訪問(wèn)的頁(yè)碼。Activity就額外實(shí)現(xiàn)了獲取SharedPreferences的方法getPreferences(int),它只需要開(kāi)發(fā)者提供文件的打開(kāi)模式,自動(dòng)以Activity的類(lèi)名作為文件名。

SharedPreferences取值時(shí)是直接將給定主鍵在Map中的值強(qiáng)制轉(zhuǎn)換成所需要的值,所以如果用putInt存儲(chǔ)了整型卻用getBoolean()來(lái)取,并不會(huì)自動(dòng)轉(zhuǎn)換成布爾型,而是直接拋出異常,所以要使用要注意保持類(lèi)型一致。

另外如果沒(méi)有存儲(chǔ)過(guò)某個(gè)主鍵,SharedPreferences會(huì)返回null值,而對(duì)于String、Set這些類(lèi)型同樣可以存儲(chǔ)null值,這樣就不能確定null是不是真是存儲(chǔ)的數(shù)據(jù)了。因此SharedPreferences還提供了contains (String key)方法來(lái)檢查給定的主鍵是真的存了null,還是因?yàn)椴](méi)有這個(gè)鍵值對(duì)才返回的null。

SharedPreferences的優(yōu)缺點(diǎn)

之前講過(guò)所以讀取過(guò)的SharedPreferences的文件都會(huì)被緩存在Map里放在內(nèi)存中,以便下次直接快速訪問(wèn),因?yàn)榭焓耂haredPreferences的一大優(yōu)點(diǎn)。但是也因?yàn)槎急尘彺?,而且存放格式是XML,所以SharedPreferences不宜存放過(guò)多的鍵值對(duì),值的內(nèi)容也不能太大。再者SharedPreferences只支持最基本的幾種類(lèi)型,存儲(chǔ)一些用戶(hù)基本信息也足夠了。

如果對(duì)設(shè)備有root權(quán)限,那么就可以直接訪問(wèn)/data/data/(packagename)/shared_prefs/目錄,將XML文件轉(zhuǎn)出來(lái)查看。或者直接用在adb shell下直接用cat指令觀察數(shù)據(jù)的改變,非常的方便。

綜合而言,存儲(chǔ)一些內(nèi)容較小、類(lèi)型簡(jiǎn)單的數(shù)據(jù),SharedPreferences絕對(duì)是***對(duì)象。

責(zé)任編輯:龐桂玉 來(lái)源: 安卓開(kāi)發(fā)精選
相關(guān)推薦

2023-11-09 08:22:38

2011-05-31 17:32:32

Android SharedPref

2022-08-04 18:50:12

Navigator瀏覽器設(shè)備

2023-12-09 08:58:30

AndroidActivity啟動(dòng)模式

2023-12-05 08:20:57

Android系統(tǒng)

2020-04-13 10:37:46

API編程設(shè)計(jì)

2012-07-25 13:25:11

ibmdw

2023-11-06 07:23:06

API開(kāi)發(fā)生態(tài)系統(tǒng)

2011-09-07 13:30:48

Android WidTabWidget

2020-07-09 08:01:48

JavaScriptES模塊

2023-11-26 09:06:46

2020-06-18 09:16:20

JavaScript緩存API

2023-10-26 11:19:21

指針Go

2013-09-13 15:01:58

2021-05-25 05:25:24

MySQL數(shù)據(jù)庫(kù)

2019-11-29 16:21:22

Spring框架集成

2017-01-20 08:30:19

JavaScriptfor循環(huán)

2023-05-06 08:53:13

2012-02-06 13:52:33

JavaScript

2020-07-29 09:13:28

JavaScript開(kāi)發(fā)技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产色网| 我要看一级片 | 久久看片| 视频国产一区 | 婷婷久久一区 | 偷拍亚洲色图 | www.嫩草| 97人人超碰 | 国产精品一区二区三区四区五区 | 亚洲精品欧美 | 欧美精品tv | 四虎影| 91在线观看免费视频 | av av在线| 日本xx视频免费观看 | 亚洲精品丝袜日韩 | 国产日产欧产精品精品推荐蛮挑 | 国产精品视频久久 | 尤物视频在线免费观看 | 国产成人99久久亚洲综合精品 | 国产在线小视频 | 99精品国产一区二区青青牛奶 | 超碰免费在线 | 亚洲欧美综合精品久久成人 | 亚洲美女一区 | 美女久久久久久久久 | 亚洲精品在线视频 | 成人aaa视频| 成人午夜精品一区二区三区 | 国产视频精品免费 | 精品成人av | 国产色| 国产成人免费网站 | www.日日操| 日韩精品在线观看免费 | 在线久草 | 精品久久久久久久久久久院品网 | 久久免费资源 | 成人一区二区三区在线观看 | 久久久久国产精品一区 | 999精品视频在线观看 |