SharedPreferences優(yōu)化總結

SharedPreferences(后續(xù)簡稱SP)為我們提供了輕量級存儲能力,方便了少量數(shù)據(jù)的持久化。

但是由于項目越來越龐大,SP操作使用不當會導致app卡頓,乃至ANR問題。

下面介紹一下操作SP的優(yōu)化點。


SP性能優(yōu)化點

SP性能變差的原因有很多。

1.原生API的限制主要有以下兩方面:

?????(1)IO瓶頸

?????(2)鎖性能差

2.對SP的不當封裝也會間接造成數(shù)據(jù)讀寫性能差。

下面會對以上三方面進行分析。


IO瓶頸

IO瓶頸造成SP性能差是最大的原因,解決了IO瓶頸,80%的性能問題就解決了。

SP的IO瓶頸包括讀取數(shù)據(jù)到內存與數(shù)據(jù)寫入磁盤兩部分。

1.讀取數(shù)據(jù)到內存有兩個場景會觸發(fā):

?????(1)SP文件沒有被加載到內存時,調用getSharedPreferences方法會初始化文件并讀入內存。

?????(2)版本低于android_H或使用了MULTI_PROCESS標志時,每次調用getSharedPreferences方法時都會讀入。

? ? ?我們可以優(yōu)化的便是(2)了。每次加載數(shù)據(jù)到內存太過影響效率。

? ?? H以下版本留存率已經很低了,基本可以忽略。

?????對于MULTI_PROCESS,可以采用ContentProvider等其他方式,效率更好,而且可避免SP數(shù)據(jù)丟失的情況。

2.數(shù)據(jù)寫入磁盤也有兩個場景會觸發(fā):

?????(1)Editor的commit方法,每次執(zhí)行時同步寫入磁盤。

?????(2)Editor的apply方法,每次執(zhí)行時在單線程池中加入寫入磁盤Task,異步寫入。

?????commit和apply的方法區(qū)別在于同步寫入和異步寫入,以及是否需要返回值。

? ?? 在不需要返回值的情況下,使用apply方法可以極大的提高性能。

?????同時,多個寫入操作可以合并為一個commit/apply,將多個寫入操作合并后也能提高IO性能。


鎖性能差

SP的get操作,會鎖定SharedPreferences對象,互斥其他操作。

SP的put操作,getEditor及commitToMemory會鎖定SharedPreferences對象,put操作會鎖定Editor對象,寫入磁盤更會鎖定一個寫入鎖。

由于鎖的緣故,SP操作并發(fā)時,耗時會徒增。減少鎖耗時,是另一個優(yōu)化點。

由于讀寫操作的鎖均是針對SP實例對象的,將數(shù)據(jù)拆分到不同的sp文件中,便是減少鎖耗時的直接方案。

降低單文件訪問頻率,多文件均攤訪問,以減少鎖耗時。

用開發(fā)機進行了簡單的性能測試(寫入均使用apply,若使用commit則多線程耗時更高):

讀寫同一文件,10個線程每個讀寫10次數(shù)據(jù):

耗時80-130ms

讀寫10個文件,每個文件由1個線程讀寫10次數(shù)據(jù):

耗時30-70ms


對SP操作的不當封裝

由于我們項目采用了插件化,所以對SP的操作涉及到了跨進程訪問。

我們采用ContentProvider方案支持跨進程訪問,并對所有SP操作均套上了ContentProvider進行訪問。

隨著項目越來越龐大,通過ContentProvider訪問造成的耗時性能也成了問題。

對ContentProvider操作SP測試,耗時是直接操作SP的4倍左右。

所以,最近項目中進行了SP的處理,對于不需要跨進程的SP操作去掉了ContentProvider,盡可能減少無謂耗時。


SP優(yōu)化的建議

1.盡量不要直接調用SharedPreferences進行讀寫操作。

若直接調用getSharedPreferences(fileName,mode).edit().putString(key,value),則對數(shù)據(jù)的操作直接耦合了fileName和key,后續(xù)想調整file和key會比較困難。

可以考慮封裝一下,譬如:

public void saveUserId(){

? ? ?getSharedPreferences(fileName,mode).edit().putString(“user_id”,value);

}

這樣做可以直接對數(shù)據(jù)訪問,而與fileName與key解耦,后續(xù)拆分與調整時會很方便。

2.將SP作為耗時操作對待,盡量減少無謂的調用。

譬如以下代碼,SP讀一次即可:

if(sp.getUserId()>0){

? ? ?int id=sp.getUserId();

? ? ?...

}

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 面試題總結 通用 安卓學習途徑, 尋找資料學習的博客網站 AndroidStudio使用, 插件使用 安卓和蘋果的...
    JingBeibei閱讀 1,873評論 2 21
  • Android 五種數(shù)據(jù)存儲的方式分別為: SharedPreferences:以Map形式存放簡單的配置參數(shù); ...
    ghroost閱讀 12,785評論 0 23
  • 一.sp是什么?能做什么? SharedPreferences(簡稱SP)是Android中很常用的數(shù)據(jù)存儲方式,...
    lemonCode閱讀 920評論 0 2
  • ——在2001屆二測前的教師月考總結會上的講話 各位老師: 再有23天就要進行二測了,今天開月考總結會暨二測動員會...
    清水一滴閱讀 477評論 0 1
  • 有一種喜悅叫驚喜,有一種滿意叫滿足,喜歡一種感覺是由內而發(fā)的,很感謝我們的相遇,有你們我很滿足,愛大家,愛每一個人!
    王兵Fineyoga閱讀 160評論 0 2

友情鏈接更多精彩內容