Android SharedPreferences总结及优化
一、SharedPreferences簡(jiǎn)介
? ? ? ?Android 中的 SharedPreferences(后續(xù)簡(jiǎn)稱SP)是輕量級(jí)的數(shù)據(jù)存儲(chǔ)方式,能夠保存簡(jiǎn)單的數(shù)據(jù)類型,比如 String、int、boolean 值等。應(yīng)用場(chǎng)合主要是數(shù)據(jù)比較少的配置信息。其內(nèi)部是以 XML 結(jié)構(gòu)保存在 /data/data/包名/shared_prefs 文件夾下,數(shù)據(jù)以鍵值對(duì)的形式保存。
? ? ? ?使用Preference來(lái)存取數(shù)據(jù),用到了SP接口和SP的一個(gè)內(nèi)部接口SharedPreferences.Editor,這兩個(gè)接口在android.content包中。
? ? ? ?調(diào)用Context.getSharedPreferences(String name,int mode)方法得到SP接口。該方法的第一個(gè)參數(shù)是文件名稱,第二個(gè)參數(shù)是操作模式。操作模式有三種:MODE_PRIVATE(私有)、MODE_WORLD_READABLE(可讀)、MODE_WORLD_WRITEABLE(可寫(xiě))。
? ? ? ?SP提供了獲得數(shù)據(jù)的方法,如getString(String key,String defValue)、getInt(String key,int defValue)等。調(diào)用SP的edit()方法返回SharedPreferences.Editor內(nèi)部接口,該接口中提供了保存數(shù)據(jù)的方法,如putString(String key,String value),putInt(String key,int value)等,調(diào)用該接口的commit()方法可以將數(shù)據(jù)進(jìn)行保存。
二、SP性能優(yōu)化點(diǎn)
SP性能變差的原因有很多。
1、原生API的限制
(1)IO瓶頸 IO瓶頸造成SP性能差是最大的原因,解決了IO瓶頸,80%的性能問(wèn)題就解決了。 SP的IO瓶頸包括讀取數(shù)據(jù)到內(nèi)存與數(shù)據(jù)寫(xiě)入磁盤(pán)兩部分。
讀取數(shù)據(jù)到內(nèi)存有兩個(gè)場(chǎng)景會(huì)觸發(fā):
數(shù)據(jù)寫(xiě)入磁盤(pán)也有兩個(gè)場(chǎng)景會(huì)觸發(fā):
(2)鎖性能差
SP的get操作,會(huì)鎖定SharedPreferences對(duì)象,互斥其他操作。 SP的put操作,getEditor及commitToMemory會(huì)鎖定SharedPreferences對(duì)象,put操作會(huì)鎖定Editor對(duì)象,寫(xiě)入磁盤(pán)更會(huì)鎖定一個(gè)寫(xiě)入鎖。 由于鎖的緣故,SP操作并發(fā)時(shí),耗時(shí)會(huì)徒增。減少鎖耗時(shí),是另一個(gè)優(yōu)化點(diǎn)。 由于讀寫(xiě)操作的鎖均是針對(duì)SP實(shí)例對(duì)象的,將數(shù)據(jù)拆分到不同的sp文件中,便是減少鎖耗時(shí)的直接方案。 降低單文件訪問(wèn)頻率,多文件均攤訪問(wèn),以減少鎖耗時(shí)。 用開(kāi)發(fā)機(jī)進(jìn)行了簡(jiǎn)單的性能測(cè)試(寫(xiě)入均使用apply,若使用commit則多線程耗時(shí)更高): 讀寫(xiě)同一文件,10個(gè)線程每個(gè)讀寫(xiě)10次數(shù)據(jù): 耗時(shí)80-130ms 讀寫(xiě)10個(gè)文件,每個(gè)文件由1個(gè)線程讀寫(xiě)10次數(shù)據(jù): 耗時(shí)30-70ms
2、對(duì)SP的不當(dāng)封裝也會(huì)間接造成數(shù)據(jù)讀寫(xiě)性能差。
由于我們項(xiàng)目采用了插件化,所以對(duì)SP的操作涉及到了跨進(jìn)程訪問(wèn)。 我們采用ContentProvider方案支持跨進(jìn)程訪問(wèn),并對(duì)所有SP操作均套上了ContentProvider進(jìn)行訪問(wèn)。 隨著項(xiàng)目越來(lái)越龐大,通過(guò)ContentProvider訪問(wèn)造成的耗時(shí)性能也成了問(wèn)題。 對(duì)ContentProvider操作SP測(cè)試,耗時(shí)是直接操作SP的4倍左右。 所以,最近項(xiàng)目中進(jìn)行了SP的處理,對(duì)于不需要跨進(jìn)程的SP操作去掉了ContentProvider,盡可能減少無(wú)謂耗時(shí)。
三、SP優(yōu)化的建議
1、盡量不要直接調(diào)用SharedPreferences進(jìn)行讀寫(xiě)操作。
若直接調(diào)用getSharedPreferences(fileName,mode).edit().putString(key,value),則對(duì)數(shù)據(jù)的操作直接耦合了fileName和key,后續(xù)想調(diào)整file和key會(huì)比較困難。 可以考慮封裝一下,譬如: public void saveUserId(){getSharedPreferences(fileName,mode).edit().putString(“user_id”,value); } 這樣做可以直接對(duì)數(shù)據(jù)訪問(wèn),而與fileName與key解耦,后續(xù)拆分與調(diào)整時(shí)會(huì)很方便。
2、將SP作為耗時(shí)操作對(duì)待,盡量減少無(wú)謂的調(diào)用。
譬如以下代碼,SP讀一次即可: if(sp.getUserId()>0){int id=sp.getUserId();... }
五、其他程序訪問(wèn)本程序的配置數(shù)據(jù)方式
? ? ? ?通過(guò)SharedPreferences創(chuàng)建的配置文件,不需要指定路徑和文件后綴名,讀取的時(shí)候也是。通常情況下,配置只是提供給本應(yīng)用程序使用的。在這里我們介紹一個(gè)小知識(shí)點(diǎn),即其他程序想使用本應(yīng)用程序的配置,那應(yīng)該如何使用SharedPreferences呢?如下: Context otherAppContext = createPackageContext("com.gary.appdisplaycontrol", Context.CONTEXT_IGNORE_SECURITY); SharedPreferences sharedPreferences = otherAppContext.getSharedPreferences("preferences",Context.MODE_WORLD_READABLE|Context.MODE_MULTI_PROCESS); 備注:必須要添加Context.MODE_MULTI_PROCESS屬性,否則會(huì)遇到其他程序讀取數(shù)據(jù)未更新問(wèn)題。
總結(jié)
以上是生活随笔為你收集整理的Android SharedPreferences总结及优化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 好听的老歌曲(怀旧经典老歌50首)
- 下一篇: 弄瓦之喜是什么意思(男孩称“弄璋之喜”,