简体   繁体   中英

Android and Kotlin coroutines: inappropriate blocking method call

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!

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) {
        Thread.sleep(1) // Flagged as inappropriate blocking call
    }

    suspend fun directRef() = withContext(Dispatchers.IO) {
        Thread.sleep(1) // 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 .

Code below can hang, because of blocking IO:

class MyService(assetManager: AssetManager) {
   private val repo = Repository(assetManager, newFixedThreadPoolContext(nThreads: 1, name: "SO QA"))

   suspend fun read(): HeritageResponse {
      return fetchHeritagesList(); // <-- please note, that we replaced IO dispatcher to single-threaded one
   }
}


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM