Jackpack DataStore 和 SharedPrefe
2022-05-11 本文已影响0人
lq_ios
简介
DataStore 有两种实现方式:Preferences 和 Proto,从中选择其一即可。您还可以向任一实现方式添加与 Android 无关的依赖项。
- Preferences DataStore 使用键存储和访问数据。此实现不需要预定义的架构,也不确保类型安全。
- Proto DataStore 将数据作为自定义数据类型的实例进行存储。此实现要求您使用协议缓冲区来定义架构,但可以确保类型安全。
Preferences DataStore添加的依赖
// Preferences DataStore (SharedPreferences like APIs)
dependencies {
implementation("androidx.datastore:datastore-preferences:1.0.0")
// optional - RxJava2 support
implementation("androidx.datastore:datastore-preferences-rxjava2:1.0.0")
// optional - RxJava3 support
implementation("androidx.datastore:datastore-preferences-rxjava3:1.0.0")
}
// Alternatively - use the following artifact without an Android dependency.
dependencies {
implementation("androidx.datastore:datastore-preferences-core:1.0.0")
}
Proto DataStore添加的依赖
// Typed DataStore (Typed API surface, such as Proto)
dependencies {
implementation("androidx.datastore:datastore:1.0.0")
// optional - RxJava2 support
implementation("androidx.datastore:datastore-rxjava2:1.0.0")
// optional - RxJava3 support
implementation("androidx.datastore:datastore-rxjava3:1.0.0")
}
// Alternatively - use the following artifact without an Android dependency.
dependencies {
implementation("androidx.datastore:datastore-core:1.0.0")
}
SharedPreferences的使用
SharedPreferences保存的数据主要是类似配置信息格式的数据。
数据的读取
获取SharedPreferences实例的获取只能通过Context的getSharedPreferences获取
//MainActivity
val sharedPref = getSharedPreferences("name", Context.MODE_PRIVATE)
//是否包含某个key
sharedPref.contains("name")
//获取所以Key-Value
val a = sharedPref.all
//获取某个值 getXXX(key,默认值)
sharedPref.getInt("age",0)
获取实例的模式:
- Context.MODE_PRIVATE : 指定该SharedPreferences数据只能被本应用程序读写
- Context.MODE_WORLD_WRITEABLE : 指定该SharedPreferences数据能被其他应用程序读,但是不能写
- Context.MODE_WORLD_READABLE : 指定该SharedPreferences数据能被其他应用程序读写
上面的Context.MODE_WORLD_WRITEABLE和Context.MODE_WORLD_READABLE在Android4.2开始就不推荐使用了,如果想给其他应用程序读写,请使用ContentProvider
数据的写入
SharedPreferences并没有提供写入的能力,写入时通过SharedPreferences实例的edit()方法
//MainActivity
val sharedPref = getSharedPreferences("",Context.MODE_PRIVATE)
with(sharedPref.edit()){
putInt("age",10)
//当编辑完成时,调用该方法提交修改
//apply() 会立即更改内存中的 SharedPreferences 对象,但会将更新异步写入磁盘。或者,您也可以使用 commit() 将数据同步写入磁盘。但是,由于 commit() 是同步的,您应避免从主线程调用它,因为它可能会暂停您的界面呈现。
apply()
//清空所有数据
clear()
//移除某个key
remove(”age“)
}
//
数据文件的查看
可以在Android Studio右下角的 Device File Explorer 中查看 data-> data -> 包名 -> shared_prefs 中 以xml的方式保存
从SharedPreference 迁移到DataStore
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "datastore_name", produceMigrations = {
context ->
listOf(SharedPreferencesMigration(context,"sp_name"))
})
迁移后原来的shared_prefs中的文件 将会被删除,可以在data-> data -> 包名 -> file -> datastore 中有新的文件生成
SharedPreference的封装使用
object SPUtils {
private fun getSharedPref(context: Context): SharedPreferences {
return context.getSharedPreferences("sp_name", Context.MODE_PRIVATE)
}
fun putInt(context: Context, key: String, value: Int) =
getSharedPref(context).edit().putInt(key, value).apply()
fun putLong(context: Context, key: String, value: Long) =
getSharedPref(context).edit().putLong(key, value).apply()
fun putFloat(context: Context, key: String, value: Float) =
getSharedPref(context).edit().putFloat(key, value).apply()
fun putBoolean(context: Context, key: String, value: Boolean) =
getSharedPref(context).edit().putBoolean(key, value).apply()
fun putString(context: Context, key: String, value: String) =
getSharedPref(context).edit().putString(key, value).apply()
fun getInt(context: Context, key: String, defValue: Int): Int =
getSharedPref(context).getInt(key, defValue)
fun getLong(context: Context, key: String, defValue: Long): Long =
getSharedPref(context).getLong(key, defValue)
fun getFloat(context: Context, key: String, defValue: Float): Float =
getSharedPref(context).getFloat(key, defValue)
fun getBoolean(context: Context, key: String, defValue: Boolean): Boolean =
getSharedPref(context).getBoolean(key, defValue)
fun getString(context: Context, key: String, defValue: String): String =
getSharedPref(context).getString(key, defValue) ?: defValue
fun remove(context: Context, key: String) {
val sharedPref = getSharedPref(context)
sharedPref.edit().remove(key).apply()
}
fun clear(context: Context) {
val sharedPref = getSharedPref(context)
sharedPref.edit().clear().apply()
}
fun contains(context: Context, key: String): Boolean {
return getSharedPref(context).contains(key)
}
fun getAll(context: Context): Map<String, *> {
return getSharedPref(context).all
}
}
通过Delegate的方式获取SharedPreference
class SharePrefDelegate(val name: String) :
ReadOnlyProperty<Context, SharedPreferences> {
override fun getValue(thisRef: Context, property: KProperty<*>): SharedPreferences {
return thisRef.getSharedPreferences(name, Context.MODE_PRIVATE)
}
}
val Context.sp by SharePrefDelegate("sp_name")
DataStore 使用
intPreferencesKey -> Preferences.Key<Int> //保存Int类型数据
doublePreferencesKey -> Preferences.Key<Double> //保存Double类型数据
stringPreferencesKey -> Preferences.Key<String> //保存String类型数据
booleanPreferencesKey ->Preferences.Key<Boolean> //保存Boolean类型数据
floatPreferencesKey -> Preferences.Key<Float> //保存Float类型数据
longPreferencesKey -> Preferences.Key<Long> //保存Long类型数据
stringSetPreferencesKey -> Preferences.Key<Set<String>> //保存Set<String>类型数据
///通过给Context添加一个扩展
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
DataStore值的获取
fun <T> getValue(key: Preferences.Key<T>, defValue: T): Flow<T> =
context.dataStore.data.catch { exception ->
emit(emptyPreferences())
}.map {
it[key] ?: defValue
}
suspend fun <T> setValue(key: Preferences.Key<T>, value: T) {
context.dataStore.edit {
it[key] = value
}
}