Skip to content

Commit

Permalink
perf: 优化数据存储逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
lisonge committed Nov 9, 2023
1 parent 1c7df7e commit df39f35
Showing 1 changed file with 26 additions and 59 deletions.
85 changes: 26 additions & 59 deletions app/src/main/java/li/songe/gkd/util/Store.kt
Original file line number Diff line number Diff line change
@@ -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)
})
}

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)
fun <T> updateStorage(stateFlow: StateFlow<T>, newState: T) {
(stateFlow as MutableStateFlow).value = newState
}


@Serializable
data class Store(
val enableService: Boolean = true,
Expand Down Expand Up @@ -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,
Expand All @@ -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
}
}
Expand Down

0 comments on commit df39f35

Please sign in to comment.