运行 代码与 kotlin 异步的最佳方式
best way for running code in async with kotlin
嗨,我想使用 jsoup 从 html 加载一个大的 table,以异步方式执行此操作的最佳方法是什么?
异步任务?协程?同步库?哪一个?我需要在获取数据时显示进度条,所以请告诉我最好的方法是什么?
更新:
我想要 运行 这个异步代码
doc: Document = Jsoup.connect(url).timeout(0).maxBodySize(0).ignoreHttpErrors(true).sslSocketFactory(setTrustAllCerts()).get()
// some code for parsing...
我建议您试用 Kotlin 协程。这将使您能够分派昂贵的或长时间的 运行 操作,即查询数据库,使网络 requests/calls 关闭到其他线程,从而不会阻塞主线程。协程帮助您避免回调的麻烦。此外,Google 弃用了 AsyncTask API(在 Android 11 中)并建议使用 Java 的并发框架或 Kotlin 协程作为实现多线程目的的方式。
在 Kotlin 中,一般方法是协程,但普通线程也是一个完全好的选择,具体取决于您在做什么。
例如,如果您的操作是线程阻塞操作,它实际上不能 运行 在协程中安全地执行,除非它在单独的线程中分派。对于协程,你需要知道 suspending 和 blocking 之间的区别(巨大的区别)。
所以如果读取HTML table是一个阻塞操作,不需要和其他协程集成,那么一个普通的线程就可以了。有许多 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线程。这就是您的 阻塞 代码将 运行 启用的内容。
嗨,我想使用 jsoup 从 html 加载一个大的 table,以异步方式执行此操作的最佳方法是什么? 异步任务?协程?同步库?哪一个?我需要在获取数据时显示进度条,所以请告诉我最好的方法是什么?
更新: 我想要 运行 这个异步代码
doc: Document = Jsoup.connect(url).timeout(0).maxBodySize(0).ignoreHttpErrors(true).sslSocketFactory(setTrustAllCerts()).get()
// some code for parsing...
我建议您试用 Kotlin 协程。这将使您能够分派昂贵的或长时间的 运行 操作,即查询数据库,使网络 requests/calls 关闭到其他线程,从而不会阻塞主线程。协程帮助您避免回调的麻烦。此外,Google 弃用了 AsyncTask API(在 Android 11 中)并建议使用 Java 的并发框架或 Kotlin 协程作为实现多线程目的的方式。
在 Kotlin 中,一般方法是协程,但普通线程也是一个完全好的选择,具体取决于您在做什么。
例如,如果您的操作是线程阻塞操作,它实际上不能 运行 在协程中安全地执行,除非它在单独的线程中分派。对于协程,你需要知道 suspending 和 blocking 之间的区别(巨大的区别)。
所以如果读取HTML table是一个阻塞操作,不需要和其他协程集成,那么一个普通的线程就可以了。有许多 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线程。这就是您的 阻塞 代码将 运行 启用的内容。