一文了解DataStore(Preferences)

前言

  1. 本篇主要介绍DataStore,包含介绍,使用等。
  2. 本篇会介绍DataStore两种实现Preferences DataStore(主要介绍)和Proto DataStore(后续介绍)。
  3. 本篇也会介绍到DataStore和SharedPreferences的不同之处,以及如何进行迁移。

简介

  • 首先,DataStore是Jetpack一部分,是一种数据存储解决方案。
  • 其次,DataStore使用协程及flow以异步、一致的方式实现数据的存储。
  • 最后是DataStore的实现,分为Preferences DataStore和Proto DataStore:
    • Preferences DataStore 类似于SharedPreferences,键值对存储,本篇的主要介绍。
    • Proto DataStore 将数据作为自定义数据类型的实例进行存储,基于Google protobuf实现。

DataStore和SharedPreferences(SP)

  • SP存在的问题:
    • 内存浪费问题,加载的数据会一直存在在内存中。
    • get方法可能会阻塞主线程。
    • apply方法虽然为异步,也可能会发生ANR。
    • SP也无法保证类型安全。
    • SP不支持跨进程。
  • DataStore的特点:
    • 基于协程和Flow实现,保证了主线程的安全性。
    • 以事务的方式进行处理,保证了操作的原子性、一致性、隔离性及持久性。
    • Preferences DataStore可以支持SP的迁移,保证数据的完整性。
  • 说明:
    • 此处只是列出SP存在的问题,并没有SP一无是处的的说法,DataStore在SP的基础上解决了不少的问题,但是也没有说SP存在的问题已经全部解决了。
    • 至少,DataStore在SP的基础上解决了如类型安全、阻塞导致anr等问题,确实这方面优于SP。

Preferences DataStore

1. 依赖引入及扩展
  • 依赖引入
implementation 'androidx.datastore:datastore-preferences:1.0.0'
  • 扩展属性,对Contex扩展属性,方便使用。
val Context.dataStore by preferencesDataStore(name = "data_store")
2. 基本使用:
编码
            //存储
            dataStore.edit { edit ->
                edit[stringPreferencesKey("data")] = "123456"
            }
            //读取
           val data =  dataStore.data.first()[stringPreferencesKey("data")]
            Log.d(TAG.TAG,"data is $data")
日志
2022-08-04 14:38:15.606 13419-13445/edu.test.demo D/Test-TAG: data is 123456
分析:
  • 一眼看起来貌似和SP区别也不大,事实上使用起来区别也确实不大。
  • 区别在于key值不再是String,而是Preferences.Key,当然这是存储string的key,存储别的类型key也不一样。
  • 有一点就是必须在协程中使用,因为edit方法是suspend方法,读取的时候data返回值为flow,操作起来也是在协程中。
3. 更新:
代码1(也就是再编辑一遍就覆盖了)如下:
  //存储
            dataStore.edit { edit ->
                edit[stringPreferencesKey("data")] = "123456"
            }

            //读取
           val data =  dataStore.data.first()[stringPreferencesKey("data")]
            Log.d(TAG.TAG,"data is $data")

            dataStore.edit { edit ->
                edit[stringPreferencesKey("data")] = "123456789"
            }

            Log.d(TAG.TAG,"data is ${ dataStore.data.first()[stringPreferencesKey("data")]}")
日志如下:
2022-08-04 14:44:25.651 13552-13579/edu.test.demo D/Test-TAG: data is 123456
2022-08-04 14:44:25.657 13552-13579/edu.test.demo D/Test-TAG: data is 123456789
代码2 调用update
 			 //存储
            dataStore.edit { edit ->
                edit[stringPreferencesKey("data")] = "123456"
            }

            //读取
           val data =  dataStore.data.first()[stringPreferencesKey("data")]
            Log.d(TAG.TAG,"data is $data")

            dataStore.updateData {
                val mutablePreference = it.toMutablePreferences()
                mutablePreference[stringPreferencesKey("data")] = "123456789"
                mutablePreference.toPreferences()
            }

            Log.d(TAG.TAG,"data is ${ dataStore.data.first()[stringPreferencesKey("data")]}")
分析:
  • 修改和SP也没有太大的却别,我们可以直接edit覆盖,也可以update。
3. DataStore支持的存储类型:
DataStore支持的存储类型从key上就可以看出,主要有七种,key类型以及调用方法如下,一眼就能看出来,就不一一
解释了:
  • Preferences.Key intPreferencesKey
  • Preferences.Key doublePreferencesKey
  • Preferences.Key stringPreferencesKey
  • Preferences.Key booleanPreferencesKey
  • Preferences.Key floatPreferencesKey
  • Preferences.Key longPreferencesKey
  • Preferences.Key<Set> stringSetPreferencesKey
4. SP到DataStore的迁移
迁移编码:
  • 主要是在扩展进行迁移,传入sp的文件名。
val Context.dataStore : DataStore<Preferences> by preferencesDataStore(name = "dataStore_setting",
    produceMigrations = { context ->
        listOf( SharedPreferencesMigration(context, "sp_data"))
    })

迁移之前我们可以看下sp文件,位置为data/data/包名/shared_prefs/sp文件名:
sp文件
迁移之后,sp文件被删除,datastore文件出现,如下:
sp迁移datastore之后文件

验证编码:
  val data = dataStore.data.first()[stringPreferencesKey("mydata")]
           Log.d(TAG.TAG,"sp->datastore,直接读取:$data")
日志如下:
2022-08-04 15:22:24.062 14131-14157/edu.test.demo D/Test-TAG: sp->datastore,直接读取:mydata123456
分析:
  • 对比可以看出,迁移之后sp文件被删除,出现datastore文件。
  • 编码验证说明已经迁移成功,sp之前存储的值,我们在datastore直接读取了出来。
  • 只有在我们使用dataStore.data.first()的时候,才会进行文件的迁移。

总结

  • 本篇主要介绍了DataStore的实现分类。
  • 本篇也介绍了DataStore在sp的基础上做了那些优化。
  • 介绍了DataStore的使用,支持数据类型,以及SP到DataStore的迁移。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Compose DataStore 是一种用于存储和读取键值对数据的 Jetpack Compose 组件。下面是一个使用 Compose DataStore 的代码示例: ```kotlin import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.platform.LocalContext import androidx.lifecycle.lifecycleScope import androidx.lifecycle.viewmodel.compose.viewModel import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.createDataStore import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch data class UserSettings(val darkMode: Boolean) class UserSettingsViewModel(private val dataStore: DataStore<Preferences>) { private val userSettingsKey = preferencesKey<Boolean>("dark_mode") val userSettingsFlow = dataStore.data .map { preferences -> UserSettings( darkMode = preferences[userSettingsKey] ?: false ) } suspend fun updateUserSettings(userSettings: UserSettings) { dataStore.edit { preferences -> preferences[userSettingsKey] = userSettings.darkMode } } } @Composable fun UserSettingsScreen(userSettingsViewModel: UserSettingsViewModel = viewModel()) { val userSettings by userSettingsViewModel.userSettingsFlow.collectAsState(UserSettings(false)) val context = LocalContext.current val darkMode by rememberSaveable { mutableStateOf(userSettings.darkMode) } LaunchedEffect(Unit) { userSettingsViewModel.userSettingsFlow.collect { settings -> darkMode = settings.darkMode } } Column { Switch( checked = darkMode, onCheckedChange = { newDarkMode -> lifecycleScope.launch { userSettingsViewModel.updateUserSettings(UserSettings(newDarkMode)) } } ) } } @Composable fun App() { val dataStore = createDataStore(name = "user_settings") val userSettingsViewModel = remember { UserSettingsViewModel(dataStore) } UserSettingsScreen(userSettingsViewModel) } ``` 这个示例演示了如何使用 Compose DataStore 来存储和读取用户设置中的暗黑模式。通过 `UserSettingsViewModel` 类,我们可以获取和更新用户设置,并通过 `UserSettingsScreen` 组件来展示和修改用户设置。在 `App` 组件中,我们创建了一个名为 "user_settings" 的 DataStore,并将其传递给 `UserSettingsViewModel`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值