android SharedPreferences解析

一矾柜,獲取SharedPreferences對象

從Activity獲取SharedPreferences對象的代碼追蹤就谜,可以發(fā)現(xiàn)其是在ContextWrapper中通過context對象方法獲取的丧荐。

mBase.getSharedPreferences(name, mode)

那context中是如何創(chuàng)建對象的呢:

1.context對象

Activity中context對象的創(chuàng)建,肯定是要從Activity的創(chuàng)建找起虹统。

ActivityThread中:handleMessage->handleLaunchActivity->performLaunchActivity->createBaseContextForActivity

ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);

在createBaseContextForActivity中可以看到ContextImpl是創(chuàng)建context的主要類车荔。

2.ContextImpl
return new ContextImpl(null, mainThread,
                packageInfo, activityToken, null, false, null, null);

通過createActivityContext方法忧便,可以看到appContext對象時(shí)new ContextImpl本身創(chuàng)建的。

由此可以知道,contex是ContextImpl對象實(shí)現(xiàn)的砍艾。

3.創(chuàng)建SharedPreferences對象

既然知道context對象的實(shí)現(xiàn)類脆荷,就可以找出SharedPreferences如何創(chuàng)建了蜓谋。

在getSharedPreferences方法中

File prefsFile = getSharedPrefsFile(name);
sp = new SharedPreferencesImpl(prefsFile, mode);
packagePrefs.put(name, sp);
return sp;

這段代碼可以知道,先獲得存儲數(shù)據(jù)的文件孤澎,然后創(chuàng)建SharedPreferencesImpl實(shí)例欠窒,SharedPreferencesImpl就是實(shí)現(xiàn)SharedPreferences的實(shí)現(xiàn)類岖妄。

3.1 獲取存儲數(shù)據(jù)的文件

getSharedPrefsFile中:

return makeFilename(getPreferencesDir(), name + ".xml");

getPreferencesDir中:

mPreferencesDir = new File(getDataDirFile(), "shared_prefs");

getDataDirFile中

return mPackageInfo.getDataDirFile();

可以看出荐虐,存儲數(shù)據(jù)的文件是在app所在數(shù)據(jù)目錄中創(chuàng)建的一個(gè)shared_prefs目錄下的文件丸凭。簡單來說如下:

new File("/data/data/"+context.getPackageName()+"/shared_prefs/"+shareName+".xml")
3.2 獲取SharedPreferencesImpl對象
SharedPreferencesImpl(File file, int mode) {
        mFile = file;
        mBackupFile = makeBackupFile(file);
        mMode = mode;
        mLoaded = false;
        mMap = null;
        startLoadFromDisk();
    }

makeBackupFile創(chuàng)建了一個(gè)備份文件惜犀,在startLoadFromDisk則使用線程獲取存儲文件中的值存儲在mMap中虽界,利用備份文件和mLoaded配合使用在多線程下使用SharedPreferences獲取存儲數(shù)據(jù)更加安全。

4.獲取對象中的參數(shù)mode
  • Context.MODE_PRIVATE:為默認(rèn)操作模式,代表該文件是私有數(shù)據(jù),只能被應(yīng)用本身訪問,在該模式下,寫入的內(nèi)容會覆蓋原文件的內(nèi)容
  • Context.MODE_APPEND:模式會檢查文件是否存在,存在就往文件追加內(nèi)容,否則就創(chuàng)建新文件.
  • Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用來控制其他應(yīng)用是否有權(quán)限讀寫該文件.
  • MODE_WORLD_READABLE:表示當(dāng)前文件可以被其他應(yīng)用讀取.
  • MODE_WORLD_WRITEABLE:表示當(dāng)前文件可以被其他應(yīng)用寫入.

mode主要在writeToFile中存儲數(shù)據(jù)后使用撇吞,而writeToFile在enqueueDiskWrite中使用牍颈,enqueueDiskWrite主要在apply方法中和commit方法中起作用琅关,而這兩個(gè)方法是修改數(shù)據(jù)后提交的方法。所以mode的功能是在寫入數(shù)據(jù)后人乓,更改存儲文件的權(quán)限作用

二碰缔,使用

1 寫入

以下是簡單寫入操作金抡。

Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();
editor.clear();

其中Editor是操作數(shù)據(jù)寫入的主要對象腌且,EditorImpl是其實(shí)現(xiàn)類。

put操作是將鍵值對存入Editor的mModified對象中巫击,mModified是個(gè)map對象精续。

commit(apply)操作是將mModified對象內(nèi)存中的數(shù)據(jù),寫入磁盤文件中顷级。

先使用MemoryCommitResult對象存儲mModified中的數(shù)據(jù)确垫,MemoryCommitResult對象主要是方便對數(shù)據(jù)寫入磁盤操作,里面含有操作狀態(tài)翔冀。

下面這個(gè)方法是實(shí)現(xiàn)數(shù)據(jù)寫入磁盤的方法

SharedPreferencesImpl.this.enqueueDiskWrite(mcr, postWriteRunnable);

而這個(gè)方法中橘蜜,writeToFile方法是實(shí)現(xiàn)數(shù)據(jù)的寫入计福。簡略為:

......
if (!mBackupFile.exists()) {
    if (!mFile.renameTo(mBackupFile)) {
        Log.e(TAG, "Couldn't rename file " + mFile
              + " to backup file " + mBackupFile);
        mcr.setDiskWriteResult(false);
        return;
    }
} else {
    mFile.delete();
}
//寫入數(shù)據(jù)操作省略
ContextImpl.setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
......

可以看出徽职,mBackupFile又起到了多線程使用安全的作用,而設(shè)置的model说订,在寫入完成后,設(shè)置了文件的權(quán)限钙姊。

2.讀取數(shù)據(jù)

一下是簡單的獲取數(shù)據(jù)操作

SharedPreferencessharedPreferences= getSharedPreferences(name,   
model);   
String value =sharedPreferences.getString(key, defValue);   

與寫入不同煞额,它不需要Editor,直接獲取數(shù)據(jù)mMap對象中的數(shù)據(jù)沾谜。

3.不同應(yīng)用間讀取數(shù)據(jù)

我們已經(jīng)知道m(xù)ode的作用,也知道存儲文件是通過context對象從對應(yīng)的應(yīng)用文件中創(chuàng)建的婚温。所以要讀取其他應(yīng)用的文件栅螟,需要兩個(gè)條件:

  • 要讀取應(yīng)用的context對象逆日,從而獲取SharedPreferences對象
  • 對應(yīng)SharedPreferences文件的model要設(shè)置為可被其他應(yīng)用讀(寫)室抽。
Context otherAppsContext = createPackageContext(packageName, Context.CONTEXT_IGNORE_SECURITY);  
  
SharedPreferences sharedPreferences = otherAppsContext.getSharedPreferences(name, Context.MODE_WORLD_READABLE);  
  
String value = sharedPreferences.getString(key, defvalue);  

總結(jié)

SharedPreferences是將數(shù)據(jù)存儲在對應(yīng)應(yīng)用目錄下shared_prefs文件夾下的xml文件中坪圾,通過context獲取SharedPreferences對象惑朦,通過Editor操作數(shù)據(jù)的寫入,mode設(shè)置SharedPreferences的模式病梢。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蜓陌,一起剝皮案震驚了整個(gè)濱河市钮热,隨后出現(xiàn)的幾起案子烛芬,更是在濱河造成了極大的恐慌隧期,老刑警劉巖飒责,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異仆潮,居然都是意外死亡宏蛉,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門性置,熙熙樓的掌柜王于貴愁眉苦臉地迎上來檐晕,“玉大人,你說我怎么就攤上這事蚌讼”倩遥” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵篡石,是天一觀的道長芥喇。 經(jīng)常有香客問我,道長凰萨,這世上最難降的妖魔是什么武通? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任境析,我火速辦了婚禮劳淆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疾捍。我一直安慰自己,他們只是感情好咙鞍,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般湿颅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谊囚,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天奠伪,我揣著相機(jī)與錄音猜拾,去河邊找鬼挎袜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛全景,可吹牛的內(nèi)容都是我干的滞伟。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼鳖轰,長吁一口氣:“原來是場噩夢啊……” “哼总处!你這毒婦竟也來了忆肾?” 一聲冷哼從身側(cè)響起旭从,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤鸽素,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓦呼,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年蹋辅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布示辈,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏累奈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間馋贤,已是汗流浹背犹芹。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工驴一, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挑辆,地道東北人例朱。 一個(gè)月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像绞灼,于是被迫代替她去往敵國和親低矮。 傳聞我的和親對象是個(gè)殘疾皇子军掂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348