0
0
Android-kotlinComparisonBeginner · 4 min read

SharedPreferences vs DataStore: Key Differences and Usage in Android

In Android, SharedPreferences is a simple API for storing small key-value pairs synchronously, while DataStore is a modern, asynchronous, and safer alternative that uses Kotlin coroutines and Flow. DataStore offers better error handling and supports both key-value and typed data storage, making it the recommended choice for new apps.
⚖️

Quick Comparison

Here is a quick side-by-side comparison of SharedPreferences and DataStore based on key factors.

FactorSharedPreferencesDataStore
API TypeSynchronous, callback-basedAsynchronous, coroutine and Flow-based
Thread SafetyNot fully thread-safeThread-safe by design
Data FormatKey-value pairs (primitive types)Key-value pairs or typed objects (Proto DataStore)
Error HandlingLimited, can cause app crashesBuilt-in error handling with exceptions
PerformanceCan block main threadNon-blocking, efficient
MigrationLegacy, older APIRecommended modern replacement
⚖️

Key Differences

SharedPreferences is the traditional way to store simple key-value data in Android. It works synchronously and can block the main thread if used improperly, which may cause UI lag. It also lacks robust error handling and is not fully thread-safe, so concurrent access can lead to data corruption.

On the other hand, DataStore is a newer, recommended API that uses Kotlin coroutines and Flow for asynchronous data storage. It is designed to be thread-safe and non-blocking, improving app performance and reliability. DataStore supports two implementations: Preferences DataStore for simple key-value pairs and Proto DataStore for typed objects using Protocol Buffers.

DataStore also provides better error handling by catching exceptions during data read/write operations, preventing app crashes. Overall, DataStore is more modern, safer, and scalable compared to SharedPreferences.

⚖️

Code Comparison

Here is how you save and read a simple string value using SharedPreferences in Kotlin.

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

// Save data
sharedPreferences.edit().putString("username", "Alice").apply()

// Read data
val username = sharedPreferences.getString("username", "") ?: ""
Output
username = "Alice"
↔️

DataStore Equivalent

Here is the equivalent code using Preferences DataStore with Kotlin coroutines.

kotlin
val Context.dataStore by preferencesDataStore(name = "prefs")

val USERNAME_KEY = stringPreferencesKey("username")

// Save data
suspend fun saveUsername(context: Context, name: String) {
  context.dataStore.edit { prefs ->
    prefs[USERNAME_KEY] = name
  }
}

// Read data
val usernameFlow: Flow<String> = context.dataStore.data
  .map { prefs -> prefs[USERNAME_KEY] ?: "" }
Output
usernameFlow emits "Alice"
🎯

When to Use Which

Choose SharedPreferences if you need a quick, simple solution for very small apps or legacy projects where migration is not feasible. It is easy to use but may cause performance issues in complex apps.

Choose DataStore for modern Android apps that require safe, asynchronous, and efficient data storage. It is the recommended approach for new projects and supports advanced features like typed data and better error handling.

Key Takeaways

DataStore is the modern, asynchronous replacement for SharedPreferences in Android.
SharedPreferences is synchronous and can block the main thread, while DataStore uses coroutines and Flow for non-blocking operations.
DataStore provides better thread safety and error handling than SharedPreferences.
Use SharedPreferences only for simple legacy needs; prefer DataStore for new Android projects.
DataStore supports both key-value and typed data storage with Protocol Buffers.