IDE警告Dispatchers.IO协程中的阻塞调用



我正在开发一个简单的应用程序,该应用程序需要来自URL调用的数据。以下是的相关代码部分

class NewsFeed : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_news_feed)
lifecycleScope.launchWhenCreated {
getNewsData()
}

private suspend fun getNewsData() {
withContext(Dispatchers.IO) {
try {
val jObj = Jsoup.connect(getString(R.string.news_feed)).get()
//many non relevant lines
BitmapFactory.decodeByteArray(URL(img).readBytes(), 0, 0)

IDE对.get((和URL((方法都发出警告,称其为";不适当的线程阻塞方法调用";

然而,如果我理解正确,我就在Dispacher.IO协同程序范围内,并且该工作是在为阻塞任务创建的另一个线程上完成的。即使我超时调用,应用程序也不会挤压或阻塞UI。

除了压制警告,我做错了什么?

您的方法是正确的,这只是检查工具的问题。

Dispatchers.IO正是为这些情况而设计的,因为它分配了额外的线程来跟上并发的阻塞IO操作。

这里的一位kotlin开发人员也解释了这一点:https://medium.com/@elizarov/阻塞-螺纹-悬挂-路线-d33e11bf4761

具体地说;将IO阻塞为挂起";建议使用

withContext(Dispatchers.IO){
...
}

用于阻止IO,例如网络呼叫或读取文件

您是对的,Job是在不同的线程上完成的,但Thread是由与协同程序一起工作的Dispatcher管理的。

如果您在该调度器中阻塞了一个Thread,这意味着在您进行阻塞时,该线程不能再用于协程。

您应该使用那些可以挂起的方法的挂起变体,以防止线程忙于等待。

如果没有挂起的替代方案,那么最好使用常规Java线程池或异步调用(如CompletalbeFuture.supplyAsync(,因为它们更适合常规阻塞代码。

最新更新