Andrew
01/13/2024, 8:38 PM@OptIn(ExperimentalResourceApi::class, DelicateCoroutinesApi::class)
private fun fetchStringResources(paths: Map<String, String>) : Map<String, String> {
val results = ConcurrentHashMap<String, String>()
runBlocking {
for ((name, path) in paths) {
GlobalScope.launch {
val string = resource(path).readBytes().decodeToString()
results.put(name, string)
}
}
delay(1_000) // without this line, `results` is empty
}
return results.toMap()
}
Part of why this comes up is because I was trying to make all calling functions suspend
functions, but Composable functions can't use that modifier. I haven't really figured out the proper structure for an application yet, but maybe I should be passing the strings map as arguments from a viewmodel (or similar)? Could that viewmodel be suspendable, so I don't have to use launch
, and can use a regular mutableMap with .await()
before passing to composable functions?Andrew
01/13/2024, 8:46 PM@OptIn(ExperimentalResourceApi::class)
suspend private fun fetchStringResources(paths: Map<String, String>) : Map<String, String> {
val results = mutableMapOf<String, String>()
for ((name, path) in paths) {
val string = resource(path).readBytes().decodeToString()
results.put(name, string)
}
return results.toMap()
}
private val allTranslations by lazy {
runBlocking { fetchTranslations() }
}
But runBlocking
should be avoided when possible.Andrew
01/13/2024, 8:49 PMrunBlocking
bit, I could use https://github.com/Kotlin/kotlinx.coroutines/issues/706#issuecomment-429922811ephemient
01/14/2024, 1:31 AMval entries = channelFlow {
for ((name, path) in paths) {
launch {
val string = resource(path).readBytes().decodeToString()
send(name to string)
}
}
}
val results = buildMap {
entries.collect { (name, string) ->
put(name, string)
}
}
ephemient
01/14/2024, 1:33 AMLaunchedEffect
to get data from suspend
functions, as per https://developer.android.com/jetpack/compose/side-effects#launchedeffectephemient
01/14/2024, 1:37 AMcollectAsState[WithLifecycle]
or produceState
work better, if it's not just one-shotAndrew
01/14/2024, 2:57 AMval alertText: String by produceState (alertTextId) {
value = lookupString(alertTextId)
}
Where lookupString
is now a suspend function 🎉Andrew
01/14/2024, 3:40 AMephemient
01/14/2024, 3:51 AMvar alertText by remember { mutableStateOf(alertTextId) }
LaunchedEffect { alertText = lookupString(alertTextId) }
e.g. alertText = alertTextId
until the suspend function returns. I'd be surprised if that's what you want…Andrew
01/14/2024, 5:05 PM