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
|
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 com.blankj.utilcode.util.LogUtils
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
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.Serializable
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import li.songe.gkd.app
|
|
||||||
import li.songe.gkd.appScope
|
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(
|
private inline fun <reified T> createStorageFlow(
|
||||||
key: String,
|
key: String,
|
||||||
crossinline init: () -> T,
|
crossinline init: () -> T,
|
||||||
): StateFlow<T> {
|
): StateFlow<T> {
|
||||||
val stateFlow =
|
val str = kv.getString(key, null)
|
||||||
MutableStateFlow(kv.getString(key, null)?.let { Singleton.json.decodeFromString<T>(it) }
|
val initValue = if (str != null) {
|
||||||
?: init())
|
try {
|
||||||
onReceives.add { _, intent ->
|
Singleton.json.decodeFromString<T>(str)
|
||||||
val extras = intent?.extras ?: return@add
|
} catch (e: Exception) {
|
||||||
val type = extras.getString("type") ?: return@add
|
e.printStackTrace()
|
||||||
val itKey = extras.getString("key") ?: return@add
|
LogUtils.d(e)
|
||||||
if (type == "update_storage" && itKey == key) {
|
null
|
||||||
stateFlow.value =
|
}
|
||||||
kv.getString(key, null)?.let { Singleton.json.decodeFromString<T>(it) } ?: init()
|
} 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
|
return stateFlow
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> updateStorage(stateFlow: StateFlow<T>, newState: T) {
|
||||||
fun sendStorageBroadcast(key: String) {
|
(stateFlow as MutableStateFlow).value = newState
|
||||||
app.sendBroadcast(Intent(app.packageName).apply {
|
|
||||||
`package` = app.packageName
|
|
||||||
putExtra("type", "update_storage")
|
|
||||||
putExtra("key", key)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
@Serializable
|
||||||
data class Store(
|
data class Store(
|
||||||
val enableService: Boolean = true,
|
val enableService: Boolean = true,
|
||||||
|
@ -113,6 +79,8 @@ val clickCountFlow by lazy {
|
||||||
recordStoreFlow.map(appScope) { r -> r.clickCount }
|
recordStoreFlow.map(appScope) { r -> r.clickCount }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val log2FileSwitchFlow by lazy { storeFlow.map(appScope) { s -> s.log2FileSwitch } }
|
||||||
|
|
||||||
fun increaseClickCount(n: Int = 1) {
|
fun increaseClickCount(n: Int = 1) {
|
||||||
updateStorage(
|
updateStorage(
|
||||||
recordStoreFlow,
|
recordStoreFlow,
|
||||||
|
@ -121,11 +89,10 @@ fun increaseClickCount(n: Int = 1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun initStore() {
|
fun initStore() {
|
||||||
receiver
|
|
||||||
storeFlow.value
|
storeFlow.value
|
||||||
recordStoreFlow.value
|
recordStoreFlow.value
|
||||||
appScope.launchTry(Dispatchers.IO) {
|
appScope.launchTry(Dispatchers.IO) {
|
||||||
storeFlow.map(appScope) { s -> s.log2FileSwitch }.collect {
|
log2FileSwitchFlow.collect {
|
||||||
LogUtils.getConfig().isLog2FileSwitch = it
|
LogUtils.getConfig().isLog2FileSwitch = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user