当前位置:   article > 正文

JetPack datastore的优势以及使用方法_datastore 优点

datastore 优点

谷歌自2020年开始推出datastore旨在替代原有SharedPreferences,解决SharedPreferences的不足

一、DataStore 相比于 SharedPreferences 优点

1. DataStore 是基于 Flow 实现的,所以保证了在主线程的安全性。

2. 以事务方式处理更新数据,事务有四大特性(原子性、一致性、 隔离性、持久性)。

3. 可以监听到操作成功或者失败结果。

5. SharedPreferences第一次加载数据时需要全量加载,当数据量大时可能会阻塞UI线程造成卡顿

6.SharedPreferencesh在执行commit() / apply()操作可能会造成ANR问题

7.相对于SharedPreferences体积更小

二、datastroe使用教程:

1.引用datastore-preferences、datastore-preferences-core库

  1. object Datastore {
  2. val preferences = "androidx.datastore:datastore-preferences:${DependencyVersionManager.datastore}"
  3. val preferences_core = "androidx.datastore:datastore-preferences-core:${DependencyVersionManager.datastore}"
  4. }

2.根据项目中SharedPreferences保存路径替换成datastore路径

通过SharedPreferencesMigration迁移类,只要从工具类中执行了独写操作,都会从SharedPreferences路径中copy一份至datastore路径下,然后自动删除原文件

  1. private val Context.dataStore by preferencesDataStore(
  2. name = Constants.Prefs.DATA_STORE_NAME,//datastore 路径
  3. produceMigrations = { context ->
  4. listOf(SharedPreferencesMigration(context, Constants.Prefs.PREFRENCE_NAME))//SharedPreferences 路径
  5. }
  6. )

3.根据不同的数据类型对datastore进行封装

  1. object EasyDataStore {
  2. /**
  3. * 存数据
  4. */
  5. @Suppress("UNCHECKED_CAST")
  6. fun <T> putData(context: Context, key: String, value: T) {
  7. runBlocking {
  8. when (value) {
  9. is Int -> putIntData(context, key, value)
  10. is Long -> putLongData(context, key, value)
  11. is String -> putStringData(context, key, value)
  12. is Boolean -> putBooleanData(context, key, value)
  13. is Float -> putFloatData(context, key, value)
  14. is Double -> putDoubleData(context, key, value)
  15. else -> throw IllegalArgumentException("This type cannot be saved to the Data Store")
  16. }
  17. }
  18. }
  19. /**
  20. * 取数据
  21. */
  22. @Suppress("UNCHECKED_CAST")
  23. fun <T> getData(context: Context, key: String, defaultValue: T): T {
  24. val data = when (defaultValue) {
  25. is Int -> getIntData(context, key, defaultValue)
  26. is Long -> getLongData(context, key, defaultValue)
  27. is String -> getStringData(context, key, defaultValue)
  28. is Boolean -> getBooleanData(context, key, defaultValue)
  29. is Float -> getFloatData(context, key, defaultValue)
  30. is Double -> getDoubleData(context, key, defaultValue)
  31. else -> throw IllegalArgumentException("This type cannot be saved to the Data Store")
  32. }
  33. return data as T
  34. }
  35. /**
  36. * 清空数据
  37. */
  38. fun clearData(context: Context) = runBlocking { context.dataStore.edit { it.clear() } }
  39. /**
  40. * 存放Int数据
  41. */
  42. private suspend fun putIntData(context: Context, key: String, value: Int) = context.dataStore.edit {
  43. it[intPreferencesKey(key)] = value
  44. }
  45. /**
  46. * 存放Long数据
  47. */
  48. private suspend fun putLongData(context: Context, key: String, value: Long) = context.dataStore.edit {
  49. it[longPreferencesKey(key)] = value
  50. }
  51. /**
  52. * 存放String数据
  53. */
  54. private suspend fun putStringData(context: Context, key: String, value: String) = context.dataStore.edit {
  55. it[stringPreferencesKey(key)] = value
  56. }
  57. /**
  58. * 存放Boolean数据
  59. */
  60. private suspend fun putBooleanData(context: Context, key: String, value: Boolean) = context.dataStore.edit {
  61. it[booleanPreferencesKey(key)] = value
  62. }
  63. /**
  64. * 存放Float数据
  65. */
  66. private suspend fun putFloatData(context: Context, key: String, value: Float) = context.dataStore.edit {
  67. it[floatPreferencesKey(key)] = value
  68. }
  69. /**
  70. * 存放Double数据
  71. */
  72. private suspend fun putDoubleData(context: Context, key: String, value: Double) = context.dataStore.edit {
  73. it[doublePreferencesKey(key)] = value
  74. }
  75. /**
  76. * 取出Int数据
  77. */
  78. private fun getIntData(context: Context, key: String, default: Int = 0): Int = runBlocking {
  79. return@runBlocking context.dataStore.data.map {
  80. it[intPreferencesKey(key)] ?: default
  81. }.first()
  82. }
  83. /**
  84. * 取出Long数据
  85. */
  86. private fun getLongData(context: Context, key: String, default: Long = 0): Long = runBlocking {
  87. return@runBlocking context.dataStore.data.map {
  88. it[longPreferencesKey(key)] ?: default
  89. }.first()
  90. }
  91. /**
  92. * 取出String数据
  93. */
  94. private fun getStringData(context: Context, key: String, default: String? = null): String = runBlocking {
  95. return@runBlocking context.dataStore.data.map {
  96. it[stringPreferencesKey(key)] ?: default
  97. }.first()!!
  98. }
  99. /**
  100. * 取出Boolean数据
  101. */
  102. private fun getBooleanData(context: Context, key: String, default: Boolean = false): Boolean = runBlocking {
  103. return@runBlocking context.dataStore.data.map {
  104. it[booleanPreferencesKey(key)] ?: default
  105. }.first()
  106. }
  107. /**
  108. * 取出Float数据
  109. */
  110. private fun getFloatData(context: Context, key: String, default: Float = 0.0f): Float = runBlocking {
  111. return@runBlocking context.dataStore.data.map {
  112. it[floatPreferencesKey(key)] ?: default
  113. }.first()
  114. }
  115. /**
  116. * 取出Double数据
  117. */
  118. private fun getDoubleData(context: Context, key: String, default: Double = 0.00): Double = runBlocking {
  119. return@runBlocking context.dataStore.data.map {
  120. it[doublePreferencesKey(key)] ?: default
  121. }.first()
  122. }
  123. }

4.在需要对数据进行读写的地方分别调用getData和putData

5.完整Datastore工具类代码见下:

  1. package com.ovopark.utils
  2. import android.content.Context
  3. import androidx.datastore.preferences.SharedPreferencesMigration
  4. import androidx.datastore.preferences.core.*
  5. import androidx.datastore.preferences.preferencesDataStore
  6. import com.ovopark.common.Constants
  7. import kotlinx.coroutines.flow.first
  8. import kotlinx.coroutines.flow.map
  9. import kotlinx.coroutines.runBlocking
  10. /**
  11. * 创建人:yaoao
  12. * 创建日期:2022/6/28.9:37
  13. * 描述:DataStore封装工具类
  14. * 修改人:
  15. * 迭代版本:
  16. * 迭代说明:
  17. */
  18. private val Context.dataStore by preferencesDataStore(
  19. name = Constants.Prefs.DATA_STORE_NAME,
  20. produceMigrations = { context ->
  21. // Since we're migrating from SharedPreferences, add a migration based on the
  22. // SharedPreferences name
  23. listOf(SharedPreferencesMigration(context, Constants.Prefs.PREFRENCE_NAME))
  24. }
  25. )
  26. object EasyDataStore {
  27. /**
  28. * 存数据
  29. */
  30. @Suppress("UNCHECKED_CAST")
  31. fun <T> putData(context: Context, key: String, value: T) {
  32. runBlocking {
  33. when (value) {
  34. is Int -> putIntData(context, key, value)
  35. is Long -> putLongData(context, key, value)
  36. is String -> putStringData(context, key, value)
  37. is Boolean -> putBooleanData(context, key, value)
  38. is Float -> putFloatData(context, key, value)
  39. is Double -> putDoubleData(context, key, value)
  40. else -> throw IllegalArgumentException("This type cannot be saved to the Data Store")
  41. }
  42. }
  43. }
  44. /**
  45. * 取数据
  46. */
  47. @Suppress("UNCHECKED_CAST")
  48. fun <T> getData(context: Context, key: String, defaultValue: T): T {
  49. val data = when (defaultValue) {
  50. is Int -> getIntData(context, key, defaultValue)
  51. is Long -> getLongData(context, key, defaultValue)
  52. is String -> getStringData(context, key, defaultValue)
  53. is Boolean -> getBooleanData(context, key, defaultValue)
  54. is Float -> getFloatData(context, key, defaultValue)
  55. is Double -> getDoubleData(context, key, defaultValue)
  56. else -> throw IllegalArgumentException("This type cannot be saved to the Data Store")
  57. }
  58. return data as T
  59. }
  60. /**
  61. * 清空数据
  62. */
  63. fun clearData(context: Context) = runBlocking { context.dataStore.edit { it.clear() } }
  64. /**
  65. * 存放Int数据
  66. */
  67. private suspend fun putIntData(context: Context, key: String, value: Int) = context.dataStore.edit {
  68. it[intPreferencesKey(key)] = value
  69. }
  70. /**
  71. * 存放Long数据
  72. */
  73. private suspend fun putLongData(context: Context, key: String, value: Long) = context.dataStore.edit {
  74. it[longPreferencesKey(key)] = value
  75. }
  76. /**
  77. * 存放String数据
  78. */
  79. private suspend fun putStringData(context: Context, key: String, value: String) = context.dataStore.edit {
  80. it[stringPreferencesKey(key)] = value
  81. }
  82. /**
  83. * 存放Boolean数据
  84. */
  85. private suspend fun putBooleanData(context: Context, key: String, value: Boolean) = context.dataStore.edit {
  86. it[booleanPreferencesKey(key)] = value
  87. }
  88. /**
  89. * 存放Float数据
  90. */
  91. private suspend fun putFloatData(context: Context, key: String, value: Float) = context.dataStore.edit {
  92. it[floatPreferencesKey(key)] = value
  93. }
  94. /**
  95. * 存放Double数据
  96. */
  97. private suspend fun putDoubleData(context: Context, key: String, value: Double) = context.dataStore.edit {
  98. it[doublePreferencesKey(key)] = value
  99. }
  100. /**
  101. * 取出Int数据
  102. */
  103. private fun getIntData(context: Context, key: String, default: Int = 0): Int = runBlocking {
  104. return@runBlocking context.dataStore.data.map {
  105. it[intPreferencesKey(key)] ?: default
  106. }.first()
  107. }
  108. /**
  109. * 取出Long数据
  110. */
  111. private fun getLongData(context: Context, key: String, default: Long = 0): Long = runBlocking {
  112. return@runBlocking context.dataStore.data.map {
  113. it[longPreferencesKey(key)] ?: default
  114. }.first()
  115. }
  116. /**
  117. * 取出String数据
  118. */
  119. private fun getStringData(context: Context, key: String, default: String? = null): String = runBlocking {
  120. return@runBlocking context.dataStore.data.map {
  121. it[stringPreferencesKey(key)] ?: default
  122. }.first()!!
  123. }
  124. /**
  125. * 取出Boolean数据
  126. */
  127. private fun getBooleanData(context: Context, key: String, default: Boolean = false): Boolean = runBlocking {
  128. return@runBlocking context.dataStore.data.map {
  129. it[booleanPreferencesKey(key)] ?: default
  130. }.first()
  131. }
  132. /**
  133. * 取出Float数据
  134. */
  135. private fun getFloatData(context: Context, key: String, default: Float = 0.0f): Float = runBlocking {
  136. return@runBlocking context.dataStore.data.map {
  137. it[floatPreferencesKey(key)] ?: default
  138. }.first()
  139. }
  140. /**
  141. * 取出Double数据
  142. */
  143. private fun getDoubleData(context: Context, key: String, default: Double = 0.00): Double = runBlocking {
  144. return@runBlocking context.dataStore.data.map {
  145. it[doublePreferencesKey(key)] ?: default
  146. }.first()
  147. }
  148. }

注意: SharedPreferences有remove方法可以单独对一些键进行删除操作,但是对datastore查找源码并没有此类方法,只能对键进行置空操作

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/309396
推荐阅读
相关标签
  

闽ICP备14008679号