Android的SharedPreferences用來(lái)存儲(chǔ)一些鍵值對(duì), 但是卻不支持跨進(jìn)程使用.
跨進(jìn)程來(lái)用的話, 當(dāng)然是放在數(shù)據(jù)庫(kù)更可靠啦, 本文主要是給作者的新庫(kù)PreferencesProvider打個(gè)廣告.
這是一個(gè)用ContentProvider實(shí)現(xiàn)的, 可以像SharedPreferences一樣用于存儲(chǔ)鍵值對(duì), 支持跨進(jìn)程使用.
SharedPreferences不支持多進(jìn)程
SharedPreferences對(duì)多進(jìn)程的支持不好, 你用什么mode也沒用, 所以官方已經(jīng)廢棄了原先的MODE_MULTI_PROCESS, 并且建議跨進(jìn)程存取值還是用ContentProvider之類的更靠譜一些.
說明見:
Context#MODE_MULTI_PROCESS
用ContentProvider來(lái)取代SharedPreferences 心路歷程
之前項(xiàng)目中為了解決跨進(jìn)程存取值的問題, 找了一個(gè)解決方案: grandcentrix/tray, 感覺還挺好用.
我們最后一次用的版本是tray的v0.10.0, 因?yàn)轫?xiàng)目發(fā)布以后后臺(tái)的崩潰里總是有相關(guān)的crash, 也是它的一個(gè)issue: https://github.com/grandcentrix/tray/issues/50
這個(gè)crash不是必現(xiàn)的, 概率比較低, 但是還是影響了一部分用戶, 當(dāng)我們解決了項(xiàng)目中的其他更重要的crash之后, 這個(gè)crash的排名就越來(lái)越靠前了.
后來(lái)作者做了一些改動(dòng), 說是在v0.11.0這個(gè)issue將會(huì)被修復(fù), 但是這個(gè)版本卻遲遲沒有發(fā)布, 似乎作者做了一些很大的改動(dòng).
為了及時(shí)補(bǔ)救, 不再讓用戶體驗(yàn)到這個(gè)隨機(jī)的崩潰, 我們決定放棄等待Tray的下個(gè)版本, 自己實(shí)現(xiàn)用ContentProvider來(lái)存取preferences.
實(shí)現(xiàn)過程用了BoD/android-contentprovider-generator來(lái)生成ContentProvider相關(guān)的代碼.
我們把存preferences的表放在了自己的數(shù)據(jù)庫(kù)里, 然后借鑒了Tray的接口, 封裝了讀取方法, 使之用起來(lái)和SharedPreferences類似.
之后我們就用自己寫的新代碼全面取代了Tray, 當(dāng)然數(shù)據(jù)庫(kù)升級(jí)時(shí)還需要對(duì)原來(lái)存在Tray里的重要數(shù)據(jù)進(jìn)行遷移.
做完了這些以后, 發(fā)現(xiàn)可以做一個(gè)像Tray一樣的庫(kù), 更簡(jiǎn)單, 造福其他人, 那么何樂而不為呢.
PreferencesProvider優(yōu)勢(shì)
- 基于ContentProvider實(shí)現(xiàn), 支持跨進(jìn)程使用;
- 采用模塊化的管理方式, 可以將preferences分組管理;
- 沒有Tray在v0.10.0版本的crash, 因?yàn)閷?shí)現(xiàn)比Tray簡(jiǎn)單, 沒有升級(jí)等功能.
(其實(shí)在我們實(shí)際項(xiàng)目的使用中, 基本上用不到對(duì)存preferences的表進(jìn)行數(shù)據(jù)庫(kù)升級(jí)的情況). - 使用方式簡(jiǎn)單, 見項(xiàng)目README說明:PreferencesProvider.
有用的工具
生成ContentProvider相關(guān)代碼:
BoD/android-contentprovider-generator
只要定義數(shù)據(jù)庫(kù)基本信息, 在json中定義表結(jié)構(gòu), 就可以生成所有相關(guān)代碼.
查看數(shù)據(jù)庫(kù):
Stetho
在Chrome中像調(diào)試網(wǎng)頁(yè)一樣看Android應(yīng)用的資源, 這個(gè)真是太好用了.
最后再次附上本文推薦的解決方案庫(kù): PreferencesProvider