import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.*
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import java.io.IOException
import kotlin.reflect.KClass
/**
* 版權(quán):Zhujiang 個(gè)人版權(quán)
*
* @author zhujiang
* 創(chuàng)建日期:12/3/20
*
* 異步獲取數(shù)據(jù)
* [getData] [readBooleanFlow] [readFloatFlow] [readIntFlow] [readLongFlow] [readStringFlow]
* 同步獲取數(shù)據(jù)
* [getSyncData] [readBooleanData] [readFloatData] [readIntData] [readLongData] [readStringData]
*
* 異步寫入數(shù)據(jù)
* [putData] [saveBooleanData] [saveFloatData] [saveIntData] [saveLongData] [saveStringData]
* 同步寫入數(shù)據(jù)
* [putSyncData] [saveSyncBooleanData] [saveSyncFloatData] [saveSyncIntData] [saveSyncLongData] [saveSyncStringData]
*
* 異步清除數(shù)據(jù)
* [clear]
* 同步清除數(shù)據(jù)
* [clearSync]
*
* 描述:DataStore 工具類
*
*/
object DataStoreUtils {
private const val preferenceName = "HarlanAndroidDataStore"
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(preferenceName)
private lateinit var dataStore: DataStore<Preferences>
/**
* init Context
* @param context Context
*/
fun init(context: Context) {
dataStore = context.dataStore
}
@Suppress("UNCHECKED_CAST")
fun <U> getSyncData(key: String, default: U): U {
val res = when (default) {
is Long -> readLongData(key, default)
is String -> readStringData(key, default)
is Int -> readIntData(key, default)
is Boolean -> readBooleanData(key, default)
is Float -> readFloatData(key, default)
is Double -> readDoubleData(key, default)
else -> throw IllegalArgumentException("This type can be saved into DataStore")
}
return res as U
}
@Suppress("UNCHECKED_CAST")
fun <U> getData(key: String, default: U): Flow<U> {
val data = when (default) {
is Long -> readLongFlow(key, default)
is String -> readStringFlow(key, default)
is Int -> readIntFlow(key, default)
is Boolean -> readBooleanFlow(key, default)
is Float -> readFloatFlow(key, default)
is Double -> readDoubleFlow(key, default)
else -> throw IllegalArgumentException("This type can be saved into DataStore")
}
return data as Flow<U>
}
suspend fun <U> putData(key: String, value: U) {
when (value) {
is Long -> saveLongData(key, value)
is String -> saveStringData(key, value)
is Int -> saveIntData(key, value)
is Boolean -> saveBooleanData(key, value)
is Float -> saveFloatData(key, value)
is Double -> saveDoubleData(key, value)
else -> throw IllegalArgumentException("This type can be saved into DataStore")
}
}
fun <U> putSyncData(key: String, value: U) {
when (value) {
is Long -> saveSyncLongData(key, value)
is String -> saveSyncStringData(key, value)
is Int -> saveSyncIntData(key, value)
is Boolean -> saveSyncBooleanData(key, value)
is Float -> saveSyncFloatData(key, value)
is Double -> saveSyncDoubleData(key, value)
else -> throw IllegalArgumentException("This type can be saved into DataStore")
}
}
fun readBooleanFlow(key: String, default: Boolean = false): Flow<Boolean> =
dataStore.data
.catch {
//當(dāng)讀取數(shù)據(jù)遇到錯(cuò)誤時(shí)枝笨,如果是 `IOException` 異常揭蜒,發(fā)送一個(gè) emptyPreferences 來(lái)重新使用
//但是如果是其他的異常,最好將它拋出去徙融,不要隱藏問題
if (it is IOException) {
it.printStackTrace()
emit(emptyPreferences())
} else {
throw it
}
}.map {
it[booleanPreferencesKey(key)] ?: default
}
fun readBooleanData(key: String, default: Boolean = false): Boolean {
var value = false
runBlocking {
dataStore.data.first {
value = it[booleanPreferencesKey(key)] ?: default
true
}
}
return value
}
fun readIntFlow(key: String, default: Int = 0): Flow<Int> =
dataStore.data
.catch {
if (it is IOException) {
it.printStackTrace()
emit(emptyPreferences())
} else {
throw it
}
}.map {
it[intPreferencesKey(key)] ?: default
}
fun readIntData(key: String, default: Int = 0): Int {
var value = 0
runBlocking {
dataStore.data.first {
value = it[intPreferencesKey(key)] ?: default
true
}
}
return value
}
fun readStringFlow(key: String, default: String = ""): Flow<String> =
dataStore.data
.catch {
if (it is IOException) {
it.printStackTrace()
emit(emptyPreferences())
} else {
throw it
}
}.map {
it[stringPreferencesKey(key)] ?: default
}
fun readStringData(key: String, default: String = ""): String {
var value = ""
runBlocking {
dataStore.data.first {
value = it[stringPreferencesKey(key)] ?: default
true
}
}
return value
}
fun readFloatFlow(key: String, default: Float = 0f): Flow<Float> =
dataStore.data
.catch {
if (it is IOException) {
it.printStackTrace()
emit(emptyPreferences())
} else {
throw it
}
}.map {
it[floatPreferencesKey(key)] ?: default
}
fun readFloatData(key: String, default: Float = 0f): Float {
var value = 0f
runBlocking {
dataStore.data.first {
value = it[floatPreferencesKey(key)] ?: default
true
}
}
return value
}
fun readDoubleData(key: String, default: Double = 0.0): Double {
var value = 0.0
runBlocking {
dataStore.data.first {
value = it[doublePreferencesKey(key)] ?: default
true
}
}
return value
}
fun readDoubleFlow(key: String, default: Double = 0.0): Flow<Double> =
dataStore.data
.catch {
if (it is IOException) {
it.printStackTrace()
emit(emptyPreferences())
} else {
throw it
}
}.map {
it[doublePreferencesKey(key)] ?: default
}
fun readLongFlow(key: String, default: Long = 0L): Flow<Long> =
dataStore.data
.catch {
if (it is IOException) {
it.printStackTrace()
emit(emptyPreferences())
} else {
throw it
}
}.map {
it[longPreferencesKey(key)] ?: default
}
fun readLongData(key: String, default: Long = 0L): Long {
var value = 0L
runBlocking {
dataStore.data.first {
value = it[longPreferencesKey(key)] ?: default
true
}
}
return value
}
suspend fun saveBooleanData(key: String, value: Boolean) {
dataStore.edit { mutablePreferences ->
mutablePreferences[booleanPreferencesKey(key)] = value
}
}
fun saveSyncBooleanData(key: String, value: Boolean) =
runBlocking { saveBooleanData(key, value) }
suspend fun saveIntData(key: String, value: Int) {
dataStore.edit { mutablePreferences ->
mutablePreferences[intPreferencesKey(key)] = value
}
}
fun saveSyncIntData(key: String, value: Int) = runBlocking { saveIntData(key, value) }
suspend fun saveStringData(key: String, value: String) {
dataStore.edit { mutablePreferences ->
mutablePreferences[stringPreferencesKey(key)] = value
}
}
fun saveSyncStringData(key: String, value: String) = runBlocking { saveStringData(key, value) }
suspend fun saveFloatData(key: String, value: Float) {
dataStore.edit { mutablePreferences ->
mutablePreferences[floatPreferencesKey(key)] = value
}
}
fun saveSyncFloatData(key: String, value: Float) = runBlocking { saveFloatData(key, value) }
suspend fun saveDoubleData(key: String, value: Double) {
dataStore.edit { mutablePreferences ->
mutablePreferences[doublePreferencesKey(key)] = value
}
}
fun saveSyncDoubleData(key: String, value: Double) = runBlocking { saveDoubleData(key, value) }
suspend fun saveLongData(key: String, value: Long) {
dataStore.edit { mutablePreferences ->
mutablePreferences[longPreferencesKey(key)] = value
}
}
fun saveSyncLongData(key: String, value: Long) = runBlocking { saveLongData(key, value) }
suspend fun clear() {
dataStore.edit {
it.clear()
}
}
suspend fun <U> remove(key: String, type: U) {
dataStore.edit { preferences ->
when (type) {
String::class -> {
val keyName = stringPreferencesKey(key)
preferences.remove(keyName)
}
Int::class -> {
val intKey = intPreferencesKey(key)
preferences.remove(intKey)
}
Boolean::class -> {
val booleanKey = booleanPreferencesKey(key)
preferences.remove(booleanKey)
}
Long::class -> {
val longKey = longPreferencesKey(key)
preferences.remove(longKey)
}
Float::class -> {
val floatKey = floatPreferencesKey(key)
preferences.remove(floatKey)
}
Double::class -> {
val doubleKey = doublePreferencesKey(key)
preferences.remove(doubleKey)
}
else -> throw IllegalArgumentException("This type can't remove into DataStore")
}
}
}
suspend fun removeSync(key: String) {
runBlocking {
val keyName = stringPreferencesKey(key)
dataStore.edit {
it.remove(keyName)
}
}
}
fun clearSync() {
runBlocking {
dataStore.edit {
it.clear()
}
}
}
}
DataStoreUtlis
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門银酬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)筐钟,“玉大人揩瞪,你說我怎么就攤上這事篓冲〕韬澹” “怎么了嗤攻?”我有些...
- 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)承粤。 經(jīng)常有香客問我闯团,道長(zhǎng)辛臊,這世上最難降的妖魔是什么房交? 我笑而不...
- 正文 為了忘掉前任候味,我火速辦了婚禮刃唤,結(jié)果婚禮上白群,老公的妹妹穿的比我還像新娘。我一直安慰自己帜慢,他們只是感情好,可當(dāng)我...
- 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著密幔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胯甩。 梳的紋絲不亂的頭發(fā)上堪嫂,一...
- 文/蒼蘭香墨 我猛地睜開眼腊满,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼培己!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起漱凝,我...
- 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎愕乎,沒想到半個(gè)月后壁公,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體感论,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡比肄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年囊陡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撞反。...
- 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響惨驶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜粗卜,卻給世界環(huán)境...
- 文/蒙蒙 一纳击、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧焕数,春花似錦、人聲如沸堡赔。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)换团。三九已至,卻和暖如春艘包,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背想虎。 一陣腳步聲響...
- 正文 我出身青樓淌友,卻偏偏與公主長(zhǎng)得像骇陈,于是被迫代替她去往敵國(guó)和親瑰抵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子你雌,可洞房花燭夜當(dāng)晚...