Android 101: Shared Preferences
Shared preferences is a built-in key-value storage.
Following code retrieves the single instance of shared preferences for the given name. The same instance is used across the application whenever it’s retrieved.
val pref = getSharedPreferences("PREF", MODE_PRIVATE)
Each shared preferences will have its own instance based on the preference name.
val pref2 = getSharedPreferences("PREF2", MODE_PRIVATE)
No matter in which context (Activity, fragment, application) it’s called, it’ll always return the same instance for the same name. This guarantees that you will always see the latest changes.
Shared preferences internal structure
Shared preferences internally has an in-memory storage on top of disk storage. Every operation goes through in-memory storage first and then to the disk if necessary.
- In-memory storage is basically a HashMap which allows O(1) runtime complexity for all operations.
val map = HashMap<String, Any>()
- Disk storage is an xml file which is structured as
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="KEY">value</string>
</map>
Get the data
All get operations are done through in-memory storage, which is immediate and IO operation is avoided. Since all operations go through in-memory first, this is guaranteed to return the latest value.
val value = pref.getString(key, null)
Note that if it’s the first time loading, it’ll wait until all data is loaded to in-memory storage from disk.
Save data via commit.
Saves the data to in-memory storage first and then synchronously writes it to disk. Since IO operation is involved, main thread is blocked until the data is written to the disk. This is an expensive operation in comparison to apply
Since the disk write operation is synchronous, success status is returned as a boolean. Therefore, you can verify that whether the operation is successful or not by checking the return value.
val result = pref.edit().putString(key, "value").commit()
Save data via apply.
Saves the data to in-memory storage first and then asynchronously writes it to disk. Main thread is not blocked and waiting for the disk operation anymore. Any read (get) after apply
will return the latest saved value because of get
operations are done through in-memory storage.
Since the disk write operation is asynchronous there is no return value as status. Therefore, you cannot verify that whether the operation is successful or not.
Use "apply" unless you need to verify the operation result.
pref.edit().putString(key, "value").apply()
Other operations
Apart from put and get, shared preferences also provides the following operations:
- Check if any key exists
- Observe shared preferences changes via listener
- Get all entries as map
- Remove a specific entry
- Clear all
Bonus
- Application scoped shared preferences are stored under:
data/data/<YOUR_APP_ID>/shared_prefs/<SHARED_PREF_NAME>.xml
- You can use Device File Explorer in Android Studio to check them.