I am working on an Android app in which I have to make changes to my HomeScreen by observing LiveData
of SharedPreferences
which lives in Settings screen. I am following MVVM architecture for it.
I have already checked this LiveData with shared preferences, but it has a lot of boilerplate in the form of creating different classes for different types of SharedPreferences
data. I am looking for something more generic. That is why I have created a LiveSharedPreference
class and getter for SharedPreferences
with Kotlin extension functions
and reified
types. Here is the custom LiveData
class and SharedPreferences
getter.
/**************** LiveSharedPreferences.kt ****************/
class LiveSharedPreferences<T : Any>(
private val sharedPreferences: SharedPreferences, private val preferenceKey: String,
private val defValue: T, private val clas: Class<T>
) : LiveData<T>() {
private val preferenceChangeListener =
SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
if (key == preferenceKey) {
// error in this line
value = sharedPreferences.get(key, defValue)
}
}
override fun onActive() {
super.onActive()
// error in this line
value = sharedPreferences.get(preferenceKey, defValue)
sharedPreferences.registerOnSharedPreferenceChangeListener(preferenceChangeListener)
}
override fun onInactive() {
sharedPreferences.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener)
super.onInactive()
}
}
/****** Custom getter with reified type T defined in Extensions.kt ******/
inline fun <reified T: Any> SharedPreferences.get(prefKey: String?, defaultValue: T? = null): T? {
return when (T::class) {
String::class -> getString(prefKey, defaultValue as? String) as T?
Int::class -> getInt(prefKey, defaultValue as? Int ?: -1) as T?
Boolean::class -> getBoolean(prefKey, defaultValue as? Boolean ?: false) as T?
Float::class -> getFloat(prefKey, defaultValue as? Float ?: -1f) as T?
Long::class -> getLong(prefKey, defaultValue as? Long ?: -1) as T?
else -> throw UnsupportedOperationException("Invalid operation")
}
}
But using this get function gives me an error:
Cannot use 'T' as reified type parameter. Use a class instead
I know it has something to do with the way I am dealing with type T
. Is there a way I can deal with this problem without much boilerplate?