Jackpack DataStore 和 SharedPreferences的使用

简介

官方文档

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)

获取实例的模式:

  1. Context.MODE_PRIVATE : 指定该SharedPreferences数据只能被本应用程序读写
  2. Context.MODE_WORLD_WRITEABLE : 指定该SharedPreferences数据能被其他应用程序读,但是不能写
  3. 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
    }
 }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容