Android系統編程入門系列之應用內鍵值對數據的簡單保存


在應用程序間及與用戶的通信交互過程中,會產生並傳遞一系列數據。針對這些數據,有部分是只在應用程序中使用的緩存數據,還有一部分是在不同位置多次或長時間使用的持久化數據。
對於緩存數據來說,通常以代碼中定義局部變量或全局變量的方式訪問使用,這種使用方式伴隨在編程的整個過程中;而持久化數據,則需要以特定的文件格式保存在系統硬盤中,使用系統提供的框架方法來訪問使用。而根據要持久化保存數據的復雜程度不同,分別有輕量級SharedPreferences,數據庫SQLiteOpenHelper或其封裝的Room,以及二進制訪問的文件File這三種方式。本文主要對持久化數據的幾種不同類型簡做介紹。

輕量級SharedPreferences

對於輕量級的鍵值對數據,可以使用android.content.SharedPreferences共享選項接口實現的相關類以持久化保存。

SharedPreferences形式保存的數據,將會以 key-value 鍵值對的形式,基於 xml 格式的文件保存在當前應用的內部存儲空間中。這種應用程序的內部存儲空間中的文件,只允許其所屬應用程序讀寫。而當應用程序卸載后,或通過 系統桌面 - 設置 - 應用管理 - 當前應用程序 - 應用數據 - 清除數據 系列操作后,其內部存儲空間也將被清空。這在一定程度上保證了內部存儲空間的數據安全。

創建文件

在AndroidSDK中已經定義SharedPreferencesImpl類作為SharedPreferences接口的實現類。

對於SharedPreferences接口的實例化對象,在可以訪問上下文環境Context對象的地方,可通過調用Context對象的getSharedPreferences(String name, int mode)方法獲取。其對應的 xml 格式文件將在當前應用程序整個生命周期過程中讀寫訪問。

或者也可以在Activity界面中,調用Activity對象的getPreferences(int mode)方法獲取,其對應的 xml 文件只在當前界面生命周期中讀寫訪問。

getSharedPreferences(String name, int mode)方法中,
參數 name 指定存儲當前數據的 xml 格式文件的文件名,其值可由開發者定義。
參數 mode 為文件的打開方式,其值通常為僅允許當前應用程序訪問該文件的Context.MODE_PRIVATE=0;在Android6.0即API23之前,該值也可以為允許多進程讀寫同步的Context.MODE_MULTI_PROCESS=4,然而該模式下會出現各種異常問題,故此版本后被棄用;在Android4.2即API17之前,mode 值也可以為允許其他應用程序讀該文件的Context.MODE_WORLD_READABLE=1,和允許其他應用程序寫該文件的Context.MODE_WORLD_WRITEABLE=2,但這兩個值均不能保證當前應用程序的數據安全性,故此版本之后被棄用。

另外,如果看不慣系統定義的SharedPreferencesImpl實現類,開發時完全可以自定義一個SharedPreferences接口的實現類,在使用context.getSharedPreferences(String name, int mode)獲取實例化對象的位置替換為自定義的實現類對象即可。

總之,在獲取SharedPreferences對象時,系統檢測當前應用程序內部存儲空間中是否有指定 namexml 格式文件,若沒有將會先創建。之后系統便會打開該文件,通過SharedPreferences對象就可以讀寫該文件了。

數據寫入文件

如果想向創建的SharedPreferences對象所在文件中寫入數據,只需要調用該對象的edit()方法,以獲取android.content.SharedPreferences.Editor接口類型的對象。

類似於界面間交互使用的Intent意圖中傳遞的數據方式,在SharedPreferences.Editor接口對象中,可以使用putBoolean(String key, boolean value)設置boolean類型的數據,putFloat(String key, float value)設置float類型的數據,putStringSet(String key, Set<String> values)設置String集合的數據等。這一系列的設置方法,其參數一 key 都是作為SharedPreferences文件中唯一的String類型的值,以標記當前數據;其參數二 value 則是要持久化保存的數據值。

另外,在SharedPreferences.Editor接口對象中,也可以使用remove (String key)方法以刪除存在的參數 key 所標記的數據內容。或者直接使用clear()方法清空設置的所有數據內容。

在通過SharedPreferences.Editor接口對象設置或刪除完數據后,調用其apply()commit()方法以一次性提交設置的所有數據,在提交之后系統會將上文設置的數據都保存到SharedPreferences文件中。

雖然commit()方法可以返回boolean值以判斷是否提交成功,但並不推薦使用該方法;使用apply()方法可以更安全的保證提交的數據成功保存。

文件讀取數據

如果想讀取SharedPreferences對象所在文件的數據,就沒有將數據寫入文件那么繁瑣的步驟了。只需要直接調用SharedPreferences對象的getBoolean(String key, boolean defValue)獲取boolean類型的數據值,getFloat(String key, float defValue)獲取float類型的數據值,getStringSet(String key, Set<String> defValues)獲取Set<String>類型的數據值等。這一系列的獲取方法,其參數一 key 與寫入文件時的設置方法中的參數 key 一致,以標記響應數據;參數二 defaultValue 則是默認的數據值,當SharedPreferences文件中並沒有保存參數 key 對應的數據時,將會返回 defaultValue 所設置的數值。

如果保存的數據量並不多,也可以直接調用SharedPreferences對象的getAll()方法,獲取Map<String, ?>集合類型的所有數據,再對得到的數據分別操作處理。

另外SharedPreferences對象的contains(String key)方法,也可以只判斷當前SharedPreferences對象所在文件中是否有參數 key 所標記的數據內容,返回boolean類型的結果。

文件修改的實時監聽

可以用SharedPreferences對象的registerOnSharedPreferenceChangeListener(SharedPreferences.OnSharedPreferenceChangeListener listener)方法,實時監聽當前SharedPreferences文件的修改操作。
參數 listenerandroid.content.SharedPreferences.OnSharedPreferenceChangeListener接口的實例化對象,在該接口中實現了onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)方法。

一旦 listener 被注冊,在參數 sharedPreferences 對應的文件中數據標記的 key 在被修改后, listener 中的onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)方法將會被系統回調。

對於已經注冊的 listener ,尤其記得要在不需要監聽之后,調用SharedPreferences對象的unregisterOnSharedPreferenceChangeListener(SharedPreferences.OnSharedPreferenceChangeListener listener),將之前注冊的OnSharedPreferenceChangeListener對象撤銷掉,以防止在后續出現內存泄漏的問題。


輕量級的SharedPreferences存儲方式,可以很方便的存儲一些簡單數據,其內存效率是比較高的。然而如果應用程序中所有的數據都使用這種存儲方式,反而使SharedPreferences文件的操作效率降低了,而且所有數據都使用這種鍵值對的形式存取,也會增加代碼量。那么有什么更合適的存儲方式適合不同類型的數據嗎?詳情請關注下一篇文章。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM