— Android, SharedPreferences, Kotlin — 1 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)
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 value4 }5}6
7sharedPrefs.registerOnSharedPreferenceChangeListener(listener)
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
.
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:
build.gradle
file:1implementation "androidx.preference:preference-ktx:1.1.1"2implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0"
PreferenceDataStore
implementation:1class MyPreferenceDataStore(context: Context) : PreferenceDataStore() {2 private val sharedPrefs = context.getSharedPreferences("my_prefs", Context.MODE_PRIVATE)3
4 override fun putString(key: String?, value: String?) {5 sharedPrefs.edit().putString(key, value).apply()6 }7
8 override fun getString(key: String?, defValue: String?): String? {9 return sharedPrefs.getString(key, defValue)10 }11}
SharedFlow
:1val preferenceDataStore = MyPreferenceDataStore(context)2
3val myKeyFlow = preferenceDataStore.createFlow("my_key", "default_value")4
5lifecycleScope.launchWhenStarted {6 myKeyFlow.collect { value ->7 // Perform actions based on the changed preference value8 }9}
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.