mirror of
https://github.com/gkd-kit/gkd.git
synced 2024-11-16 19:57:15 +08:00
perf: 优化数据存储逻辑
This commit is contained in:
parent
1c7df7e751
commit
df39f35317
|
@ -1,81 +1,47 @@
|
|||
package li.songe.gkd.util
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.Build
|
||||
import com.blankj.utilcode.util.LogUtils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.drop
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.encodeToString
|
||||
import li.songe.gkd.app
|
||||
import li.songe.gkd.appScope
|
||||
import java.util.WeakHashMap
|
||||
|
||||
|
||||
private val onReceives by lazy {
|
||||
mutableListOf<(
|
||||
context: Context?,
|
||||
intent: Intent?,
|
||||
) -> Unit>()
|
||||
}
|
||||
|
||||
private val receiver by lazy {
|
||||
object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
onReceives.forEach { fc -> fc(context, intent) }
|
||||
}
|
||||
}.apply {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
app.registerReceiver(this, IntentFilter(app.packageName), Context.RECEIVER_NOT_EXPORTED)
|
||||
} else {
|
||||
app.registerReceiver(this, IntentFilter(app.packageName))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val stateFlowToKey by lazy { WeakHashMap<StateFlow<*>, String>() }
|
||||
|
||||
private inline fun <reified T> createStorageFlow(
|
||||
key: String,
|
||||
crossinline init: () -> T,
|
||||
): StateFlow<T> {
|
||||
val stateFlow =
|
||||
MutableStateFlow(kv.getString(key, null)?.let { Singleton.json.decodeFromString<T>(it) }
|
||||
?: init())
|
||||
onReceives.add { _, intent ->
|
||||
val extras = intent?.extras ?: return@add
|
||||
val type = extras.getString("type") ?: return@add
|
||||
val itKey = extras.getString("key") ?: return@add
|
||||
if (type == "update_storage" && itKey == key) {
|
||||
stateFlow.value =
|
||||
kv.getString(key, null)?.let { Singleton.json.decodeFromString<T>(it) } ?: init()
|
||||
val str = kv.getString(key, null)
|
||||
val initValue = if (str != null) {
|
||||
try {
|
||||
Singleton.json.decodeFromString<T>(str)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
LogUtils.d(e)
|
||||
null
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
val stateFlow = MutableStateFlow(initValue ?: init())
|
||||
appScope.launch {
|
||||
stateFlow.drop(1).collect {
|
||||
withContext(Dispatchers.IO) {
|
||||
kv.encode(key, Singleton.json.encodeToString(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
stateFlowToKey[stateFlow] = key
|
||||
return stateFlow
|
||||
}
|
||||
|
||||
|
||||
fun sendStorageBroadcast(key: String) {
|
||||
app.sendBroadcast(Intent(app.packageName).apply {
|
||||
`package` = app.packageName
|
||||
putExtra("type", "update_storage")
|
||||
putExtra("key", key)
|
||||
})
|
||||
fun <T> updateStorage(stateFlow: StateFlow<T>, newState: T) {
|
||||
(stateFlow as MutableStateFlow).value = newState
|
||||
}
|
||||
|
||||
inline fun <reified T> updateStorage(stateFlow: StateFlow<T>, newState: T) {
|
||||
if (stateFlow.value == newState) return
|
||||
val key = stateFlowToKey[stateFlow] ?: error("not found stateFlow key")
|
||||
kv.encode(key, Singleton.json.encodeToString(newState))
|
||||
sendStorageBroadcast(key)
|
||||
}
|
||||
|
||||
|
||||
@Serializable
|
||||
data class Store(
|
||||
val enableService: Boolean = true,
|
||||
|
@ -113,6 +79,8 @@ val clickCountFlow by lazy {
|
|||
recordStoreFlow.map(appScope) { r -> r.clickCount }
|
||||
}
|
||||
|
||||
private val log2FileSwitchFlow by lazy { storeFlow.map(appScope) { s -> s.log2FileSwitch } }
|
||||
|
||||
fun increaseClickCount(n: Int = 1) {
|
||||
updateStorage(
|
||||
recordStoreFlow,
|
||||
|
@ -121,11 +89,10 @@ fun increaseClickCount(n: Int = 1) {
|
|||
}
|
||||
|
||||
fun initStore() {
|
||||
receiver
|
||||
storeFlow.value
|
||||
recordStoreFlow.value
|
||||
appScope.launchTry(Dispatchers.IO) {
|
||||
storeFlow.map(appScope) { s -> s.log2FileSwitch }.collect {
|
||||
log2FileSwitchFlow.collect {
|
||||
LogUtils.getConfig().isLog2FileSwitch = it
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user