Delving into Android Data Storage | SharedPreferences

Eaz Software
4 min readJan 29, 2024

--

Join us as we explore Android Data Storage. In this series, we delve into each data storage option for Android apps, uncovering their features, advantages, and ideal use cases for optimal data management in Android app development.

Establishing reliable data storage methods is crucial in Android development. While various options exist, such as Internal Storage, External Storage, and SQLite Databases, this discussion centers on SharedPreferences and its advanced alternatives: DataStore, SharedPreferences, and EncryptedSharedPreferences. Join us as we delve into these solutions, examining their intricacies, benefits, and practical applications within the Android landscape.

SharedPreferences:

SharedPreferences is a lightweight data storage mechanism in Android that stores key-value pairs persistently. It’s commonly used for storing small amounts of primitive data types, such as user preferences, settings, or application state. SharedPreferences provides a simple API for reading and writing data and is accessible across different components of an app. However, it lacks built-in encryption, making it less suitable for storing sensitive information.

It’s commonly used for storing user preferences, settings, or other app-related configurations. Here is some examples for it :

Step 1: Initializing SharedPreferences

First, we need to obtain an instance of SharedPreferences. We typically do this using the getSharedPreferences() method, passing in a unique name for our SharedPreferences file and a mode (usually MODE_PRIVATE for private access within our app).

val sharedPreferences = context.getSharedPreferences("my_preferences", Context.MODE_PRIVATE)

"my_preferences" is a unique identifier for the SharedPreferences file. Each SharedPreferences file is identified by a unique name, which allows multiple SharedPreferences files to coexist within the app or even across different apps on the same device. By providing a name for the SharedPreferences file, we can create separate instances of SharedPreferences to store different types of data or to maintain distinct sets of preferences/settings within the app.

Step 2: Writing Data to SharedPreferences

We can use the SharedPreferences.Editor interface to modify the contents of our SharedPreferences file. Let's say we want to save a user's name and email address:

val editor = sharedPreferences.edit()
editor.putString("user_name", "John Doe")
editor.putString("user_email", "john.doe@example.com")
editor.apply()

editor.apply() is used to persistently save the changes made to the SharedPreferences file. It applies the modifications asynchronously in the background and does not block the UI thread. Once apply() is called, the changes are committed to the SharedPreferences file.

It’s important to note that editor.apply() is preferred over editor.commit() for asynchronous and non-blocking saving of SharedPreferences changes. apply() is more efficient as it writes the changes to disk asynchronously, while commit() writes the changes synchronously and may block the UI thread, causing potential performance issues, especially when dealing with larger datasets.

Step 3: Retrieving Data from SharedPreferences

To retrieve data from SharedPreferences, we can use methods like getString(), getInt(), getBoolean(), etc.

val userName = sharedPreferences.getString("user_name", "")
val userEmail = sharedPreferences.getString("user_email", "")

The second parameter "" in the getString() method call represents the default value that will be returned if the specified preference key ("user_name" or "user_email") is not found in the SharedPreferences file or if its value is null.

Step 4: Editing Data in SharedPreferences

To modify existing data in SharedPreferences, we follow a similar process using the SharedPreferences.Editor interface.

val editor = sharedPreferences.edit()
editor.putString("user_name", "Jane Smith")
editor.apply()

Step 5: Removing Data from SharedPreferences

If we need to remove data from SharedPreferences, we can use the remove() method.

val editor = sharedPreferences.edit()
editor.remove("user_email")
editor.apply()

Step 6: Clearing SharedPreferences

To clear all data from SharedPreferences, we can use the clear() method.

val editor = sharedPreferences.edit()
editor.clear()
editor.apply()

Other usages:

contains(): Checks if a preference with the specified key exists in the SharedPreferences file.

val containsEmail = sharedPreferences.contains("user_email")

getAll(): Retrieves all key-value pairs from the SharedPreferences file as a Map.

val allPreferences = sharedPreferences.all

registerOnSharedPreferenceChangeListener(): Registers a listener to be notified of changes to SharedPreferences values. in this example we will be updating UI based on Preference changes:

val listener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
if (key == "night_mode_enabled") {
val nightModeEnabled = sharedPreferences.getBoolean(key, false)
if (nightModeEnabled) {
// Enable night mode settings (e.g., change background color)
} else {
// Disable night mode settings (e.g., revert background color)
}
}
}

// Register the listener
sharedPreferences.registerOnSharedPreferenceChangeListener(listener)

// Unregister the listener when it's no longer needed (e.g., in onDestroy())
// sharedPreferences.unregisterOnSharedPreferenceChangeListener(listener)

Additional Tips:

Here are some additional usage patterns and best practices for working with SharedPreferences in Android development:

Use Constants for Keys: Define constants for SharedPreferences keys to ensure consistency and avoid typos. This improves code readability and maintainability.

object SharedPreferencesKeys {
const val USER_NAME = "user_name"
const val USER_EMAIL = "user_email"
}

Encapsulate SharedPreferences Access: Encapsulate SharedPreferences access within a dedicated class or object to abstract away implementation details and provide a clean interface for interacting with SharedPreferences.

class AppPreferences(private val sharedPreferences: SharedPreferences) {

fun getUserName(): String {
return sharedPreferences.getString(SharedPreferencesKeys.USER_NAME, "") ?: ""
}

fun setUserName(userName: String) {
sharedPreferences.edit().putString(SharedPreferencesKeys.USER_NAME, userName).apply()
}

// Similar methods for other preferences
}

Use Default Values Effectively: Provide meaningful default values when retrieving SharedPreferences values. Avoid using empty strings ("") or other default values that may not make sense in the context of your app.

val userName = sharedPreferences.getString(SharedPreferencesKeys.USER_NAME, "Guest")

Batch Operations: If you need to perform multiple SharedPreferences operations together, batch them using a single apply() call to minimize disk writes and improve efficiency.

sharedPreferences.edit {
putString(SharedPreferencesKeys.USER_NAME, "John")
putString(SharedPreferencesKeys.USER_EMAIL, "john@example.com")
// Other operations
}.apply()

If you like this post please don’t forget to follow me to get notify whenever there is new post in here :]

--

--