与 kotlin 异步运行代码的最佳方法

Posted

技术标签:

【中文标题】与 kotlin 异步运行代码的最佳方法【英文标题】:best way for running code in async with kotlin 【发布时间】:2020-06-01 19:04:16 【问题描述】:

嗨,我想使用 jsoup 从 html 加载一个大表,以异步方式执行此操作的最佳方法是什么? 异步任务?协程? doasync 库?哪一个?我需要在获取数据时显示进度条,所以请告诉我最好的方法是什么?

更新: 我想异步运行这段代码

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

【问题讨论】:

在这三个中,我会使用协程,也许会输入LiveData 以供 UI 层使用。 @CommonsWare 你能给我一个例子吗? 【参考方案1】:

在 Kotlin 中,一般方法是协程,但普通线程也是一个完全不错的选择,具体取决于您正在做什么。

例如,如果您的操作是线程阻塞操作,它实际上不能在协程中安全运行,除非它在单独的线程中分派。对于协程,你需要知道suspendingblocking之间的区别(巨大的区别)。

所以如果读取 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 线程。这就是您的阻塞代码将运行的地方。

【讨论】:

【参考方案2】:

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

【讨论】:

谢谢你,你能给我一个例子吗?我更新了我的问题并添加了我想异步运行的代码 @Clay07g 提供的答案显示了如何完成此操作(;

以上是关于与 kotlin 异步运行代码的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Android Studio 运行单个 Kotlin 类

全新升级 Kotlin系统入门与进阶

来自阻塞代码的异步/等待 kotlin 协程

Kotlin初识Kotlin

学习干货最新Android Kotlin入门教程指南,2023最新!

Kotlin 协程Flow 异步流 ③ ( 冷流 | 流被收集时运行 | 流的连续性 )