Reputation: 5297
I'm trying to use a Sequence (e.g. FileTreeWalk returned from File.walk) inside a coroutine, but my implementation keeps blocking the ui thread.
Is there a good way to handle Sequences and mapping the items within coroutines?
Here is a snipped of my code:
override fun onResume() {
super.onResume()
launch {
apkFiles = searchMyFiles(rootDir).await()
showMyFiles()
}
}
private fun searchMyFiles(dir: File): Deferred<MutableList<MyFile>> {
return async {
dir.walk().filter { !it.isDirectory }
.filter { it.extension.equals(MY_EXTENSION, true) }
.map { MyFile(it, context) }.filter { it.valid
}.sorted().toMutableList()
}
}
Upvotes: 1
Views: 614
Reputation: 200168
Although there's no evidence from your code, I'll make a guess that your default dispatcher, set in the CoroutineScope
you implicitly use, is Dispatchers.Main
(the UI thread). You keep using the same dispatcher for your background job instead of Dispatchers.IO
.
A second point is that you use async-await
for no purpose, you should use withContext
instead and declare your function as suspend fun
.
Given the above, your code should be
override fun onResume() {
super.onResume()
launch {
apkFiles = searchMyFiles(rootDir)
showMyFiles()
}
}
private suspend fun searchMyFiles(dir: File) : MutableList<MyFile> =
withContext(Dispatchers.IO) {
dir.walk()
.filter { !it.isDirectory }
.filter { it.extension.equals(MY_EXTENSION, true) }
.map { MyFile(it, context) }
.filter { it.valid }
.sorted()
.toMutableList()
}
}
Upvotes: 5