Potato
Potato copied to clipboard
Android:Room replace Sharedpreferences
Room 替换 SP 的可行性实践
对比
SharedPreference
简称SP,使用键值对的形式保存原始类型的数据,默认以XML格式的文件来存储这些数据
- 适用场景:存储量小、简单的数据
- 优缺点:有自己的内存级的缓存,在数据量小的时候读取较快,但是跨进程不安全,数据量大的时候加载缓慢,全量写入,容易引起ANR
sqlite, Room
Room并不是一个数据库,他是在 sqlite 的基础上提供了一个抽象层,让用户能够在充分利用 SQLite 的强大功能的同时,获享更强健的数据库访问机制。并保留了灵活的接口适配层。
@Database(entities = [KeyValue::class], version = 1, exportSchema = true)
abstract class KvStore : RoomDatabase(), CoroutineScope by MainScope() {
companion object {
val database by lazy {
Room.databaseBuilder(
SwUtils.application, KvStore::class.java, "key_value_database.db"
)
.allowMainThreadQueries()
.build()
}
fun <T : Any> get(key: String, defaultValue: T): T {
val type = defaultValue::class.simpleName ?: ""
val value = database.dao().get(key, type)
return try {
val v = when (defaultValue) {
is String -> value
is Boolean -> value == "true"
is Int -> value.toInt()
is Float -> value.toFloat()
is Double -> value.toDouble()
else -> Gson().fromJson(value, defaultValue::class.java)
}
v as T
} catch (e: Throwable) {
defaultValue
}
}
fun <T : Any> set(key: String, value: T) {
val type = value::class.simpleName ?: ""
val v = when (value) {
is String, is Boolean, is Int, is Float, is Double -> value.toString()
else -> Gson().toJson(value)
}
database.dao().insertReplace(KeyValue(key, type, v))
}
inline fun <reified T> liveData(key: String, sticky: Boolean = true): MediatorLiveData<T> {
var realSticky = sticky
val type = T::class.simpleName ?: ""
val mld = MediatorLiveData<T>()
mld.addSource(database.dao().liveData(key, type)) {
if (realSticky) {
mld.value = try {
Gson().fromJson(it, T::class.java)
} catch (e: Throwable) {
null
}
} else {
realSticky = true
}
}
return mld
}
}
abstract fun dao(): KeyValueDao
}
@Entity(primaryKeys = ["key", "type"])
data class KeyValue(
@ColumnInfo(name = "key", defaultValue = "")
var key: String = "",
@ColumnInfo(name = "type", defaultValue = "")
var type: String = "",
@ColumnInfo(name = "value", defaultValue = "")
var value: String = ""
)
@Dao
abstract class KeyValueDao : BaseDao<KeyValue>() {
@Query("SELECT value from KeyValue WHERE `key` = :key AND type = :type")
abstract fun get(key: String, type: String): String
@Query("SELECT value from KeyValue WHERE `key` = :key AND type = :type")
abstract fun liveData(key: String, type: String): LiveData<String>
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun insertReplace(obj: KeyValue): Long
}
最后
可复制代码或者根据该思路扩展