Kotlin协程、Android异步任务和async/await之间的区别

12

我了解了 Kotlin 协程的原理,但是对于 Kotlin 协程、Android Async.execute() 和 Async await 之间有些混淆。Kotlin 协程在后台运行且不会阻塞 UI 线程,但是当我们使用 Android AsyncTask(重写了方法 doInBackground, onPostExecute 和 onProgressUpdate)时也会在后台线程上执行计算并将结果发布到 UI 线程。

Async-await 返回一个 Deffered 对象,这意味着结果显然会在未来返回。

有人可以解释一下它们之间的区别吗?


1
本质上它们做的事情是相同的,但只是在细节和API设置方面有所不同。它们都异步执行任务,并提供了获取未来结果的方法,而await只是让同一线程等待该未来结果,从本质上强制任务变成同步。 - Jack
2
我看到的主要区别是,AsyncTask 默认在 SingleThreadPoolExecuter 中运行,因此默认情况下无法并行运行多个 AsyncTask。除此之外,如果没有正确处理,AsyncTask 通常会留下内存泄漏问题。简而言之,Kotlin 协程是一种优雅的异步调用方式,不需要任何回调接口,与 RXjava 非常相似。 - ADM
1
@jackz314 如果我这样使用 async/await:myAPIService.getWeather(location).await(),然后是 myAPIService.getDetails(id).await(),你的意思是先获取 getWeather 的结果再获取 getDetails 吗? - Amit Ranjan
1
如果你调用await(),那么线程将等待任务完成后执行下一行代码,这与普通同步代码的行为相同。 - Jack
它们都解决同一个问题,即后台处理。关键是哪个是最好的。我个人使用协程。Google已经弃用了AsyncTask。它们只是有不同的实现方式。 - coroutineDispatcher
这篇文章讲解了线程和协程的区别,以简单易懂的方式介绍了进程、线程和协程的多任务处理。 - Manoj Mohanty
1个回答

4

让我们来分解一下:

Kotlin 协程在后台运行

协程可以在后台运行

不会阻塞 UI 线程

让我们谈谈什么是协程:

协程可以被视为传递给一个协程构建器函数(例如 launch {})的代码。

按照定义,当启动协程时,在其中遇到的暂停函数(suspend functions)不会阻塞相应的 Thread;它们会"暂停"协程。

当到达暂停点时,就好像你在告诉那段代码:"稍后回电报告我结果" 。暂停点可以被视为一个回调。

让我们看一个例子:

fun main() {
 val job = MainScope().launch {
  doSomeWork()
}

suspend fun doSomeWork() {/*expensive work goes here*/}
}

当执行doSomeWork()时,代码将暂停协程,即挂起修饰符指示协程框架可以执行其他与协程相关的工作,然后在doSomeWork()完成时返回该点。
由于这个协程是使用MainScope()启动的,因此它将在主线程中启动。这就是我说协程可以在后台线程中运行但不总是这样的原因。在这种情况下,它并没有阻塞UI线程。
另一方面,AsyncTask 是(从API 30开始已弃用)在后台线程中执行任务并将结果发布回UI线程的机制。
对于CoroutineScope.async{}CoroutineScope.launch{}之间的区别,我们可以查看每个函数的返回值。正如我在示例中所示的那样,launch{}返回一个Job,代表协程本身的生命周期。使用Job,您可以cancel()join()协程;您可以控制其生命周期。正如您所提到的,async{}返回一个Deffered<T>,代表一个未来的值。当在Deffered<T>上调用await()时,协程将被挂起,直到结果准备好被使用。

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