使用 Kotlin 异步运行代码的最佳方法是什么?

3

嗨,我想使用Jsoup从HTML中加载一个大表格,最好的异步方式是什么?AsyncTask?协程?Doasync库?哪一个?我需要在获取数据时显示进度条,请告诉我最好的方式是什么?

更新: 我想在异步模式下运行此代码。

doc: Document = Jsoup.connect(url).timeout(0).maxBodySize(0).ignoreHttpErrors(true).sslSocketFactory(setTrustAllCerts()).get()
// some code for parsing...

在这三个中,我会使用协程,可能将其引入到 LiveData 中供 UI 层使用。 - CommonsWare
@CommonsWare,你能给我一个例子吗? - user11453013
2个回答

2
在Kotlin中,一般的方法是使用协程,但正常的线程也是完全可行的选项,这取决于你要做什么。例如,如果你的操作是一个线程阻塞操作,除非它在单独的线程中分派,否则它实际上不能在协程中安全地运行。对于协程,你需要知道挂起和阻塞之间的区别(巨大的区别)。因此,如果读取HTML表格是一个阻塞操作,并且你不需要与其他协程集成,那么正常的线程就可以很好地工作。有许多Java示例可转换为Kotlin。使用协程,你可以做如下操作:
suspend fun getDoc() = withContext(Dispatchers.IO) {
    Jsoup.connect(url).timeout(0).maxBodySize(0).ignoreHttpErrors(true).sslSocketFactory(setTrustAllCerts()).get()
}

然后,在您的主要代码中:
fun main() = runBlocking {

    val deferredDoc = async { getDoc() }

    // Do whatever.... it's not being blocked...

    val doc = deferredDoc.await() // SUSPENDING CALL - but not blocking
}

显然,您的程序结构与此示例不同,因为它完全取决于您想要用“getDoc()”异步执行的代码。
例如,您甚至可以拥有另一个协程,在“deferredDoc.await()”挂起时执行,而无需创建另一个线程。这就是协程的好处。
在上面的结构中,我们有3个保证的线程:
- 主线程,始终被阻塞 - 主协程线程。这通常是协程运行的地方。Kotlin协程将在此线程内异步运行您的协程,使用挂起。 - IO线程。这是您的阻塞代码所在的位置。

0
我建议你尝试使用Kotlin协程。这将使您能够调度昂贵或长时间运行的操作,例如查询数据库,向其他线程发出网络请求/调用,从而不会阻塞主线程。协程可以帮助您避免回调的麻烦。此外,Google已经弃用了AsyncTask API(在Android 11中),并建议使用Java的并发框架或Kotlin协程作为多线程目的的方法。

谢谢,你能给我一个例子来做这件事吗?我更新了我的问题并且添加了我要在异步中运行的代码。 - user11453013
@Clay07g提供的答案展示了如何完成此操作(; - Mayokun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接