美文网首页
DataStore 使用

DataStore 使用

作者: wind_sky | 来源:发表于2021-05-27 15:06 被阅读0次

    DataStore 是Jetpack 组件之一,是Google 开发出来用以代替SharedPreferences 的。DataStore 是基于 Flow 实现的,一种新的数据存储方案,它提供了两种实现方式:

    • Proto DataStore:存储类的对象(typed objects ),通过 protocol buffers 将对象序列化存储在本地
    • Preferences DataStore:以键值对的形式存储在本地和 SharedPreferences 类似,但是 DataStore 是基于 Flow 实现的,不会阻塞主线程,并且保证类型安全

    Preferences DataStore 相比于 SharedPreferences 优点

    • DataStore 是基于 Flow 实现的,所以保证了在主线程的安全性
    • 以事务方式处理更新数据,事务有四大特性(原子性、一致性、 隔离性、持久性)
    • 没有 apply() 和 commit() 等等数据持久的方法
    • 自动完成 SharedPreferences 迁移到 DataStore,保证数据一致性,不会造成数据损坏
    • 可以监听到操作成功或者失败结果

    一. 使用

    1. 依赖
    implementation "androidx.datastore:datastore-preferences:1.0.0-beta01"
    implementation "androidx.datastore:datastore:1.0.0-beta01"
    
    // protobuf
     implementation "com.google.protobuf:protobuf-javalite:3.10.0"
    
    2. 创建DataStore 对象
    // 'settings' 是存储在本地的文件名
    private val prefDataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
    
    3. 读和写

    这里以String 类型为例,其余数据类型同理,
    读数据

    // 返回一个Flow
    fun getString(key: String, dft: String = ""): Flow<String> {
            return prefDataStore.data.catch { e ->  // Flow 中发生异常可使用这种方式捕获,catch 块是可选的
                if (e is IOException) {
                    e.printStackTrace()
                    emit(emptyPreferences())
                } else {
                    throw e
                }
            }.map {
                it[stringPreferencesKey(key)] ?: dft       // stringPreferencesKey 生成一个读取string 类型的key
            }
    }
    

    写数据

    suspend fun putString(key: String, value: String) {
            // edit 函数需要在挂起环境中执行
            prefDataStore.edit { pref -> pref[stringPreferencesKey(key)] = value }
    }
    

    上面的读和写都是在协程的环境中执行的,是非阻塞的,如果要使用阻塞的形式,可以通过 runBlocking方法,如:

    fun getStringSync(key: String, dft: String = ""): String {
            var value = dft
            runBlocking {
                prefDataStore.data.first {
                    value = it[stringPreferencesKey(key)] ?: dft
                    true          // 这里返回true 表示取到Flow 中的第一个数据后停止收集Flow 中的数据
                }
            }
            return value
    }
    

    迁移SharedPreferences
    迁移 SharedPreferences 到 DataStore 只需要 2 步

    • 在构建 DataStore 的时候,需要传入一个 SharedPreferencesMigration
    dataStore = context.createDataStore(
        name = PREFERENCE_NAME,
        migrations = listOf(
            SharedPreferencesMigration(
                context,
                SharedPreferencesRepository.PREFERENCE_NAME    // 创建SharedPreferences 时的文件名
            )
        )
    )
    
    • 当 DataStore 对象构建完了之后,需要执行一次读取或者写入操作,即可完成 SharedPreferences 迁移到 DataStore,当迁移成功之后,会自动删除 SharedPreferences 使用的文件

    注意: 只从 SharedPreferences 迁移一次,因此一旦迁移成功之后,应该停止使用 SharedPreferences。

    二. 对比

    与MMKV 的对比


    image.png

    Google 提供的一个SharedPreferences 和DataStore 对比图


    image.png

    参考文档:
    https://juejin.cn/post/6881442312560803853
    https://juejin.cn/post/6888847647802097672
    https://developer.android.com/topic/libraries/architecture/datastore#kotlin

    相关文章

      网友评论

          本文标题:DataStore 使用

          本文链接:https://www.haomeiwen.com/subject/yxirsltx.html