3

我正在开发一个需要来自 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。

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

4

2 回答 2

0

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

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

此处的一位 kotlin 开发人员也对此进行了解释: https ://medium.com/@elizarov/blocking-threads-suspending-coroutines-d33e11bf4761

特别是“阻塞 IO 到挂起”段落建议使用

withContext(Dispatchers.IO){
   ...
}

用于阻塞 IO,例如网络调用或读取文件

于 2020-10-22T16:49:20.233 回答
-1

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

如果您Thread在该调度程序中阻塞 a ,则意味着该线程在您阻塞时不能再用于协程。

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

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

于 2020-10-22T07:28:47.713 回答