《SharedPreferences的使用及原始碼淺析》讀書筆記

weixin_33860722發表於2017-11-06

《讀書筆記》文集目的是梳理下自己對文章的理解。人不是機器,讀過的文章(知識點)肯定會忘記。但是如果有個筆記記錄,當我們再讀時,大腦會快速復原。推薦大家。
大家可以在主頁右下方看《原創技術部落格》和《平日積累總結》文集。(咳咳,如果用的是移動裝置,簡書好像還沒支援,只能自己找。。)

SharedPreferences 原始碼其實並不是複雜。大家可以直接讀原始碼。當然我推薦一篇文章。SharedPreferences的使用及原始碼淺析這篇部落格,作者分析的很詳細,幾乎是把原始碼放上來了。給作者一個贊。

之前覺得SharedPreferences特別簡單,所以也就沒有看過原始碼,但看了之後發現,之前的理解有些並不對,比如:

“每次從sp讀資料都會進行一次io操作,效能不好。。”
“sp的apply操作和commit操作的區別類似fragment的commit操作和commitNow操作。。”

讀了程式碼,你會發現,上面的兩個都不對。
我說下sp大致的一個流程:
application 的context實現類中有一個map<String,File> 這裡的string就是sp的name。我們根據這個sp的名字就能找到對應的磁碟中的File檔案(xml檔案),如果沒有這個檔案,那麼就新建sp對應的磁碟檔案。然後接下來的操作是不是應該 把sp包成一個緩衝流進行讀寫IO操作呢?錯!不是這樣的。拿到對應的File物件後,會從application 的context實現類另外一個map ArrayMap<File,SharedPreferencesImpl>中找File對應的SharedPreferencesImpl(其實,這個ArrayMap是根據包名在往外一個map中找的,不過這個不是重點,所以忽略也沒事),我們context.getSharedPreferences()得到的sp返回值就是這個。所以讀寫操作都是操作的SharedPreferencesImpl方法。如果沒有File對應的SharedPreferencesImpl,那麼會傳入File物件,new 一個SharedPreferencesImpl。注意,這這個構造方法中,會開啟一個執行緒將.xml這個file中的資料讀到SharedPreferencesImpl一個map 成員變數中。即,重新開啟app,第一次獲取對應的sp時,會把磁碟的資料載入記憶體中。)之後的讀操作,都是從記憶體的這個map中讀取的。寫操作,會使用Editor。我們會把寫入的key-value,刪除操作等先暫存到Editor的map中(刪除操作用的this當佔位符)。然後當我們呼叫Editor的commit/apply後,會先把Editor的map中的資料同步到SharedPreferencesImpl的map中。然後會根據使用的是Editor的commit/apply操作來進行不同的操作:commit操作不會新開執行緒來將Editor的map中的資料同步到磁碟file中;apply操作** 會** 新開執行緒來將Editor的map中的資料同步到磁碟file中。所以還是使用apply操作吧。

  1. 第一個問題上面文字中已經回答了。
  2. 第二個問題。sp的apply操作和commit操作的區別是同步和非同步的區別。fragment的commit操作和commitNow操作是要不要馬上執行fragment的commit還是把fragment放到主執行緒looper 列隊的最後等待執行。

分析就到這裡吧~~~

相關文章