I have the following class:
class Repository(
private val assetManager: AssetManager,
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) {
suspend fun fetchHeritagesList(): HeritageResponse = withContext(ioDispatcher) {
try {
// TODO Blocking method call?
val bufferReader = assetManager.open("heritages.json").bufferedReader()
...
and I'm wondering why do I get a warning in the open("heritages.json")
saying Innapropriate blocking method call
? isn't the withContext(ioDispatcher)
fixing that?
Thanks for the explanation!
Kotlin Coroutines on Android Suspend Function In Kotlin Coroutines As it is known that when the user calls the delay () function in any coroutine, it will not block the thread in which it is running, while the delay () function is called one can do some other operations like updating UI and many more things.
One way to check for cancellation is by calling the ensureActive function. All suspend functions from kotlinx.coroutines such as withContext and delay are cancellable. If your coroutine calls them, you shouldn't need to do any additional work.
Coroutines were added to Kotlin in version 1.3 and are based on established concepts from other languages. On Android, coroutines help to manage long-running tasks that might otherwise block the main thread and cause your app to become unresponsive. Over 50% of professional developers who use coroutines have reported seeing increased productivity.
Suspend Function In Kotlin Coroutines As it is known that when the user calls the delay () function in any coroutine, it will not block the thread in which it is running, while the delay () function is called one can do some other operations like updating UI and many more things.
IntelliJ inspection that looks for blocking calls inside suspendable functions isn't powerful enough to see through a level of indirection between Dispatchers.IO
and its usage in withContext
. Here's a minimal reproducer of the issue:
class IoTest {
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
suspend fun indirectRef() = withContext(ioDispatcher) {
FileInputStream(File("dummy.txt")) // Flagged as inappropriate blocking call
}
suspend fun directRef() = withContext(Dispatchers.IO) {
FileInputStream(File("dummy.txt")) // Not flagged
}
}
However, unlike in my case, your ioDispatcher
is exposed for injection through the constructor so you could just as easily supply Dispatchers.Main
instead of it, and that would constitute inappropriate blocking.
Unfortunately I haven't yet heard of any way to formally specify the contract of a dispatcher as "tolerating blocking calls", so that you could enforce it in the constructor.
There is already a similar issue open on YouTrack.
EDIT: As of the build from March 16, 2022, there seems to be a regression that flags IO calls even inside a withContext(IO)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With