Skip to content

Observing SharedPreferences Changes in Android

Android, SharedPreferences, Kotlin1 min read

SharedPreferences is a key-value store in Android that allows you to persist small amounts of data across app restarts. It is commonly used to store user preferences, settings, and other application state variables. Sometimes, it becomes necessary to observe changes in the SharedPreferences values and perform certain actions accordingly. In this article, we will explore how to observe SharedPreferences changes in Android using Kotlin.

To begin with, let's assume we have a SharedPreferences instance named sharedPrefs that we want to monitor for changes:

1val sharedPrefs = getSharedPreferences("my_prefs", Context.MODE_PRIVATE)

Using OnSharedPreferenceChangeListener

The easiest way to observe SharedPreferences changes is by implementing an OnSharedPreferenceChangeListener. This listener interface provides a callback method onSharedPreferenceChanged that gets invoked whenever a preference value changes. Here's an example:

1val listener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
2 if (key == "my_key") {
3 // Perform actions based on the changed preference value
4 }

Make sure to register the listener using registerOnSharedPreferenceChangeListener to start receiving change notifications. Don't forget to unregister the listener when it's no longer needed using unregisterOnSharedPreferenceChangeListener.

Using Flow and SharedFlow (AndroidX Preference Library)

Starting from AndroidX Preference Library 1.1.0-alpha01, you can also use Flow and SharedFlow to observe SharedPreferences changes. This approach allows you to use the Kotlin Coroutines API for asynchronous programming. To use it, follow these steps:

  1. Add the following dependencies to your project's build.gradle file:
1implementation "androidx.preference:preference-ktx:1.1.1"
2implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0"
  1. Create a PreferenceDataStore implementation:
1class MyPreferenceDataStore(context: Context) : PreferenceDataStore() {
2 private val sharedPrefs = context.getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
4 override fun putString(key: String?, value: String?) {
5 sharedPrefs.edit().putString(key, value).apply()
6 }
8 override fun getString(key: String?, defValue: String?): String? {
9 return sharedPrefs.getString(key, defValue)
10 }
  1. Observe changes using SharedFlow:
1val preferenceDataStore = MyPreferenceDataStore(context)
3val myKeyFlow = preferenceDataStore.createFlow("my_key", "default_value")
5lifecycleScope.launchWhenStarted {
6 myKeyFlow.collect { value ->
7 // Perform actions based on the changed preference value
8 }

Here, we create a MyPreferenceDataStore implementation by extending PreferenceDataStore. We override the necessary methods to read and write preferences to the underlying SharedPreferences instance.

Using createFlow, we create a SharedFlow that emits values whenever the "my_key" preference changes. Then, we collect the flow in a coroutine scope and perform the desired actions based on the emitted values.

Observing SharedPreferences changes can be essential when you need to respond to preference updates in real-time. By implementing listeners or using Flow and SharedFlow, you can easily react to changes in SharedPreferences values and update your app's behavior accordingly.