Skip to content

Instantly share code, notes, and snippets.

@Bloody-Badboy
Created March 7, 2021 16:37
Show Gist options
  • Save Bloody-Badboy/9afd179f3cdf315d1ead92defb83eee7 to your computer and use it in GitHub Desktop.
Save Bloody-Badboy/9afd179f3cdf315d1ead92defb83eee7 to your computer and use it in GitHub Desktop.
Android SharedPreferences extentions
import android.content.Context
import android.content.Context.MODE_PRIVATE
import android.content.SharedPreferences
import kotlinx.coroutines.channels.ConflatedBroadcastChannel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
interface ExamplePreferenceStore {
var isLoggedIn: Boolean
val isLoggedInFlow: Flow<Boolean>
}
class ExampleSharedPreferenceStorage(
context: Context
) : ExamplePreferenceStore {
private val isLoggedInChannel: ConflatedBroadcastChannel<Boolean> by lazy {
ConflatedBroadcastChannel<Boolean>().also { channel ->
channel.offer(isLoggedIn)
}
}
private val changeListener = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
when (key) {
PREF_LOGGED_IN -> isLoggedInChannel.offer(isLoggedIn)
}
}
private val prefs: Lazy<SharedPreferences> = lazy { // Lazy to prevent IO access to main thread.
context.applicationContext.getSharedPreferences(
PREFS_NAME, MODE_PRIVATE
).apply {
registerOnSharedPreferenceChangeListener(changeListener)
}
}
override var isLoggedIn: Boolean by BooleanPreference(
prefs,
PREF_LOGGED_IN,
false
)
override val isLoggedInFlow: Flow<Boolean>
get() = isLoggedInChannel.asFlow()
companion object {
const val PREFS_NAME = "example"
const val PREF_LOGGED_IN = "pref_logged_in"
}
}
import android.annotation.SuppressLint
import android.content.SharedPreferences
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
@SuppressLint("ApplySharedPref")
private inline fun SharedPreferences.edit(
commit: Boolean = false,
action: SharedPreferences.Editor.() -> Unit
) {
val editor = edit()
action(editor)
if (commit) {
editor.commit()
} else {
editor.apply()
}
}
class BooleanPreference(
private val preferences: Lazy<SharedPreferences>,
private val name: String,
private val defaultValue: Boolean
) : ReadWriteProperty<Any, Boolean> {
override fun getValue(
thisRef: Any,
property: KProperty<*>
): Boolean {
return preferences.value.getBoolean(name, defaultValue)
}
override fun setValue(
thisRef: Any,
property: KProperty<*>,
value: Boolean
) {
preferences.value.edit { putBoolean(name, value) }
}
}
class StringPreference(
private val preferences: Lazy<SharedPreferences>,
private val name: String,
private val defaultValue: String?
) : ReadWriteProperty<Any, String?> {
override fun getValue(
thisRef: Any,
property: KProperty<*>
): String? {
return preferences.value.getString(name, defaultValue)
}
override fun setValue(
thisRef: Any,
property: KProperty<*>,
value: String?
) {
preferences.value.edit { putString(name, value) }
}
}
class IntPreference(
private val preferences: Lazy<SharedPreferences>,
private val name: String,
private val defaultValue: Int
) : ReadWriteProperty<Any, Int> {
override fun getValue(
thisRef: Any,
property: KProperty<*>
): Int {
return preferences.value.getInt(name, defaultValue)
}
override fun setValue(
thisRef: Any,
property: KProperty<*>,
value: Int
) {
preferences.value.edit { putInt(name, value) }
}
}
class LongPreference(
private val preferences: Lazy<SharedPreferences>,
private val name: String,
private val defaultValue: Long
) : ReadWriteProperty<Any, Long> {
override fun getValue(
thisRef: Any,
property: KProperty<*>
): Long {
return preferences.value.getLong(name, defaultValue)
}
override fun setValue(
thisRef: Any,
property: KProperty<*>,
value: Long
) {
preferences.value.edit { putLong(name, value) }
}
}
class StringSetPreference(
private val preferences: Lazy<SharedPreferences>,
private val name: String,
private val defaultValue: Set<String>?
) : ReadWriteProperty<Any, Set<String>?> {
override fun getValue(
thisRef: Any,
property: KProperty<*>
): Set<String>? {
return preferences.value.getStringSet(name, defaultValue)
}
override fun setValue(
thisRef: Any,
property: KProperty<*>,
value: Set<String>?
) {
preferences.value.edit { putStringSet(name, value) }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment