Đây là một cách sử dụng Thuộc tính được ủy quyền của Kotlin mà tôi đã chọn từ đây , nhưng đã mở rộng và cho phép một cơ chế đơn giản để nhận / thiết lập các thuộc tính SharedPreference.
Đối với String
, Int
, Long
, Float
hay Boolean
, nó sử dụng các getter chuẩn SharePreference (s) và setter (s). Tuy nhiên, đối với tất cả các lớp dữ liệu khác, nó sử dụng GSON để tuần tự hóa thành a String
, cho trình thiết lập. Sau đó giải tuần tự hóa cho đối tượng dữ liệu, cho getter.
Tương tự như các giải pháp khác, điều này đòi hỏi phải thêm GSON làm phụ thuộc trong tệp lớp của bạn:
implementation 'com.google.code.gson:gson:2.8.6'
Đây là một ví dụ về một lớp dữ liệu đơn giản mà chúng tôi muốn có thể lưu và lưu trữ vào SharedPreferences:
data class User(val first: String, val last: String)
Đây là một lớp thực hiện các đại biểu tài sản:
object UserPreferenceProperty : PreferenceProperty<User>(
key = "USER_OBJECT",
defaultValue = User(first = "Jane", last = "Doe"),
clazz = User::class.java)
object NullableUserPreferenceProperty : NullablePreferenceProperty<User?, User>(
key = "NULLABLE_USER_OBJECT",
defaultValue = null,
clazz = User::class.java)
object FirstTimeUser : PreferenceProperty<Boolean>(
key = "FIRST_TIME_USER",
defaultValue = false,
clazz = Boolean::class.java
)
sealed class PreferenceProperty<T : Any>(key: String,
defaultValue: T,
clazz: Class<T>) : NullablePreferenceProperty<T, T>(key, defaultValue, clazz)
@Suppress("UNCHECKED_CAST")
sealed class NullablePreferenceProperty<T : Any?, U : Any>(private val key: String,
private val defaultValue: T,
private val clazz: Class<U>) : ReadWriteProperty<Any, T> {
override fun getValue(thisRef: Any, property: KProperty<*>): T = HandstandApplication.appContext().getPreferences()
.run {
when {
clazz.isAssignableFrom(String::class.java) -> getString(key, defaultValue as String?) as T
clazz.isAssignableFrom(Int::class.java) -> getInt(key, defaultValue as Int) as T
clazz.isAssignableFrom(Long::class.java) -> getLong(key, defaultValue as Long) as T
clazz.isAssignableFrom(Float::class.java) -> getFloat(key, defaultValue as Float) as T
clazz.isAssignableFrom(Boolean::class.java) -> getBoolean(key, defaultValue as Boolean) as T
else -> getObject(key, defaultValue, clazz)
}
}
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) = HandstandApplication.appContext().getPreferences()
.edit()
.apply {
when {
clazz.isAssignableFrom(String::class.java) -> putString(key, value as String?) as T
clazz.isAssignableFrom(Int::class.java) -> putInt(key, value as Int) as T
clazz.isAssignableFrom(Long::class.java) -> putLong(key, value as Long) as T
clazz.isAssignableFrom(Float::class.java) -> putFloat(key, value as Float) as T
clazz.isAssignableFrom(Boolean::class.java) -> putBoolean(key, value as Boolean) as T
else -> putObject(key, value)
}
}
.apply()
private fun Context.getPreferences(): SharedPreferences = getSharedPreferences(APP_PREF_NAME, Context.MODE_PRIVATE)
private fun <T, U> SharedPreferences.getObject(key: String, defValue: T, clazz: Class<U>): T =
Gson().fromJson(getString(key, null), clazz) as T ?: defValue
private fun <T> SharedPreferences.Editor.putObject(key: String, value: T) = putString(key, Gson().toJson(value))
companion object {
private const val APP_PREF_NAME = "APP_PREF"
}
}
Lưu ý: bạn không cần cập nhật bất cứ điều gì trong sealed class
. Các tính chất phân cấp là Object / Singletons UserPreferenceProperty
, NullableUserPreferenceProperty
và FirstTimeUser
.
Để thiết lập một đối tượng dữ liệu mới để lưu / nhận từ SharedPreferences, giờ đây thật dễ dàng như thêm bốn dòng:
object NewPreferenceProperty : PreferenceProperty<String>(
key = "NEW_PROPERTY",
defaultValue = "",
clazz = String::class.java)
Cuối cùng, bạn có thể đọc / ghi giá trị vào SharedPreferences chỉ bằng cách sử dụng by
từ khóa:
private var user: User by UserPreferenceProperty
private var nullableUser: User? by NullableUserPreferenceProperty
private var isFirstTimeUser: Boolean by
Log.d("TAG", user) // outputs the `defaultValue` for User the first time
user = User(first = "John", last = "Doe") // saves this User to the Shared Preferences
Log.d("TAG", user) // outputs the newly retrieved User (John Doe) from Shared Preferences