协程 kotlin
Recently, Kotlin Coroutines introduce an advanced and efficient approach of concurrency, which can be used on Android to simplify async tasks. As a matter of fact, this approach is much more simple, comprehensive, and robust in comparison with other approaches in Android. This essay aims to introduce and discuss some basic concepts of Kotlin Coroutines for Android developers.
最近,Kotlin Coroutines引入了一种先进且高效的并发方法,该方法可以在Android上用于简化异步任务。 实际上,与Android中的其他方法相比,该方法更加简单,全面和可靠。 本文旨在为Android开发人员介绍和讨论Kotlin Coroutines的一些基本概念。
总览 (Overview)
Asynchronous programming is a means of parallel programming in which a unit of work runs separately from the main application thread and notifies the calling thread of its completion, failure or progress. Therefore, it can be considered as an essential issue in advanced Android apps because as an Android developer you have to handle expensive and heavy tasks away from UI thread. It means you can manage some tasks in the background without avoiding UI freezes and annoying user experiences. Android supports some traditional asynchronous programming solutions such as Thread and AsyncTask. However, the problem has not solved yet completely. In other words, AsyncTask and Thread can easily produce memory leaks and overheads, and the problem of Callback Hell is one of the main negative consequences in traditional programming as well.
异步编程是并行编程的一种方式,其中一个工作单元与主应用程序线程分开运行,并向调用线程通知其完成,失败或进度。 因此,它可以被视为高级Android应用程序中的基本问题,因为作为Android开发人员,您必须处理UI线程之外的昂贵且繁重的任务。 这意味着您可以在后台管理某些任务,而无需避免UI冻结和令人讨厌的用户体验。 Android支持一些传统的异步编程解决方案,例如Thread和AsyncTask。 但是,问题尚未完全解决。 换句话说,AsyncTask和Thread容易产生内存泄漏和开销,而Callback Hell的问题也是传统编程中的主要负面后果之一。
Additionally, Google has studied accurately some best practices and some feedback for concurrency recently that are used by Android developers. In fact, the modern concurrency approach in Android is classified in three categories by Google for developers: Coroutines (Suspend-able computations), RxKotlin or RxJava (Schedulers, Observer, and Observable), and LiveData (Observable Data Holder). First, Kotlin Coroutines introduce a new approach of concurrency, which can be used on Android to simplify Async tasks. Also, developers indicated that this way could be a best solution in Android. Second, although RxKotlin or RxJava is one of the efficient mechanism in Android for concurrency as well as asynchronous programming, it takes a lot of time to get to know and use it effectively in practice by developers. Third, developers mentioned on that study, which LiveData could be a useful approach for concurrency in Android, but they want a complete solution to address this issue.
此外,Google准确地研究了Android开发人员最近使用的一些最佳实践和并发反馈。 实际上,谷歌为开发人员将Android中的现代并发方法分为三类:协程(可暂停计算),RxKotlin或RxJava(Schedulers,Observer和Observable)以及LiveData(可观察数据持有者)。 首先,Kotlin Coroutines引入了一种新的并发方法,该方法可以在Android上用于简化异步任务。 此外,开发人员表示,这种方式可能是Android中的最佳解决方案。 其次,尽管RxKotlin或RxJava是Android中用于并发以及异步编程的有效机制之一,但开发人员实际上需要花费大量时间来有效地了解和使用它。 第三,开发人员在该研究中提到,LiveData可能是实现Android并发的有用方法,但他们希望有一个完整的解决方案来解决此问题。
Eventually, the best solution should follow three main principles in Google view, and they believe that Kotlin Coroutines provides these ideas as follows:
最终,最佳解决方案应遵循Google观点中的三个主要原则,并且他们认为Kotlin Coroutines提供以下想法:
- Simple: It should be an easy solution to learn. 简单:这应该是一个易于学习的解决方案。
- Comprehensive: It should be a solution that covers all cases and solutions. 全面:应该是一个涵盖所有案例和解决方案的解决方案。
- Robust: It should be a built-in teasing story. 健壮:应该是内置的戏弄故事。
Kotlin协程简介 (Introduction to Kotlin Coroutines)
Fundamentally, Kotlin Coroutines use the concept of Continuation-Passing Style programming(CPS). This method of programming includes passing the control flow of the program as an argument to functions. This argument is called Continuation in Kotlin. In a word, a continuation is similar to a callback, but it is more system level generally. Furthermore, Coroutines can be suspended and resumed. It means you can have a long-running task that you can execute gradually. So, you can be able to pause it any number of times, and resume it when you want to use it again. An important note is that using a number of Kotlin Coroutines will not produce memory overheads to your app. Suspend and resume work with each other to replace traditional callbacks. For more information, if a Coroutines is suspended, the current stack frame in Kotlin is copied and saved for future usages. When it resumes, the stack frame is copied back from where it was stored and, starts running again. Also, when all Coroutines are suspended, the main thread would be free for their routine works. In addition to this section, main-safety is another key features of Kotlin Coroutines. In short, this means appropriate suspend functions are always safe to call from the main thread. They should always allow any thread to call them without knowing what they want to do.
从根本上说,Kotlin Coroutines使用连续传递样式编程(CPS)的概念。 这种编程方法包括将程序的控制流作为参数传递给函数。 这个论点在Kotlin被称为延续。 简而言之,延续类似于回调,但一般来说是系统级的。 此外,协程可以暂停和恢复。 这意味着您可以执行可以长期执行的长期任务。 因此,您可以暂停它多次,然后在您想再次使用它时将其恢复。 一个重要的注意事项是,使用许多Kotlin协程不会对您的应用程序产生内存开销。 彼此暂停和恢复工作以替换传统的回调。 有关更多信息,如果协程被挂起,则Kotlin中的当前堆栈帧将被复制并保存以备将来使用。 恢复时,堆栈帧将从其存储位置复制回去,并再次开始运行。 同样,当所有协同程序都挂起时,主线程将可以进行日常工作。 除本节外,主要安全性是Kotlin Coroutines的另一个主要功能。 简而言之,这意味着从主线程调用总是合适的挂起函数。 他们应该始终允许任何线程调用它们而无需知道他们想做什么。
Coroutines = Co + Routines
协程= Co +例程
Co means cooperation and Routines means functions. This means that when functions cooperate with each other, we call it as Coroutines.
Co表示合作, Routines表示功能。 这个 意味着当函数彼此协作时,我们将其称为协程。
暂停功能 (Suspending functions)
Suspending functions might suspend the execution of the current Coroutine without blocking the current thread. Also, instead of returning a value, it knows in which context the caller suspended it. Thus, by using this feature, it can resume appropriately when ready. This helps further in memory optimizations of the CPU and multi-tasking. In spite of blocking a thread, suspending functions are less expensive because they do not need a context switching. A suspending function can be created by adding the keyword suspend to a function. A suspending function can be just only called from a coroutine or another suspending function. For example:
挂起函数可能会在不阻塞当前线程的情况下挂起当前协程的执行。 另外,它不返回值,而是知道调用方在哪个上下文中挂起了它。 因此,通过使用此功能,它可以在准备就绪时适当地恢复。 这有助于进一步优化CPU和多任务的内存。 尽管阻塞了线程,但由于挂起函数不需要上下文切换,因此挂起函数的成本较低。 可以通过在函数中添加关键字“ suspend”来创建函数。 只能从协程或其他暂停函数调用暂停函数。 例如:
suspend fun sampleSuspend(){ println("Kotlin Coroutines")}
协程建造者 (Coroutine Builders)
Basically, suspending functions cannot be invoked from regular functions. Therefore, the library provides a set of functions to start Coroutines from them. There are a lot of Coroutine builders provided by Kotlin Coroutines, including:
基本上,暂挂函数不能从常规函数中调用。 因此,该库提供了一组从中启动协程的函数。 Kotlin Coroutines提供了很多Coroutine构建器,包括:
launch: This creates a new coroutine. It just fires and forgets, and does not wait for the response. If an uncaught exception occurs, that would abrupt the program flow.
launch :这将创建一个新的协程。 它只是引发并忘记,并且不等待响应。 如果发生未捕获的异常,那将使程序流程突然中断。
async: This fires and waits for the response.
异步 :这将触发并等待响应。
runBlocking: This is similar to launch except that inside a runBlocking everything would be on the same Coroutine.
runBlocking :这与启动类似,不同之处在于,在runBlocking内部,所有内容都在同一协同程序上。
run: This is a basic Coroutine.
运行 :这是基本的协程。
CoroutineScope: This helps define the lifecycle of Kotlin Coroutines. It can be application-wide or bound to an Activity.
CoroutineScope :这有助于定义Kotlin Coroutines的生命周期。 它可以在应用程序范围内或绑定到活动。
Dispatchers: This defines thread pools to launch your Kotlin Coroutines in.
调度程序 :这定义了线程池以启动您的Kotlin协程。
As it clear from above, there are two approaches for starting Kotlin Coroutines with various usages:
从上面可以清楚地看出,有两种方法可以启动具有各种用法的Kotlin协程:
launch builder: It does not wait for the response.
启动生成器 :它不等待响应。
async builder: will start a new coroutine, and it lets you to return a result (returns an instance of Deffered
), with a suspend function called await. async builder :将启动一个新的协程,并允许您使用称为await的暂停函数返回结果(返回Deffered
的实例)。
For instance:
例如:
suspend fun sampleSuspend() { println("Kotlin Coroutines")
}fun main(args: Array) = runBlocking {println("Start")
val x = launch(CommonPool) {
delay(2000)
sampleSuspend()
println("launch")
}
println("Finish")
x.join() //The sampleSuspend method does not run because the function just only fires and forgets. We should use the join function, which waits for the completion.}
The output of above sample codes is: start, finish, Kotlin Coroutines, and launch would be printed respectively and vertically.
以上示例代码的输出是:开始,完成,Kotlin协程和启动将分别和垂直打印。
The difference between join and await is join waits for completion of launch. await looks for the returned result.
join和await之间的区别是join等待启动完成。 等待查找返回的结果。
调度员 (Dispatchers)
All Kotlin Coroutines must run in a dispatcher even when they are running on the main thread. Coroutines can suspend themselves, and the dispatcher is the element, which knows how to resume them. You can use these dispatchers for the following situations:
即使所有Kotlin协程程序都在主线程上运行,它们也必须在调度程序中运行。 协程可以暂停自身,而调度程序是元素,它知道如何恢复它们。 您可以在以下情况下使用这些调度程序:
1.Dispatchers.Default: CPU-intensive work, such as sorting large lists, performing complex calculations.
1.Dispatchers.Default : CPU密集型工作,例如对大型列表进行排序,执行复杂的计算。
2. Dispatchers.IO: networking or reading and writing from files (any input and output)
2. Dispatchers.IO :网络连接或文件读写(任何输入和输出)
3. Dispatchers.Main: recommended dispatcher for performing UI-related events such as showing lists in a RecyclerView, updating view, and so on.
3. Dispatchers.Main :推荐的调度程序,用于执行与UI相关的事件,例如在RecyclerView中显示列表,更新视图等。
For instance:
例如:
suspend fun fetchUser(): User { return GlobalScope.async(Dispatchers.IO) {
// make network call
// return user
}.await()
}
Kotlin协程的作用域 (Scopes in Kotlin Coroutines)
Scopes in Kotlin Coroutines are extremely useful because we have to cancel the background task as soon as the activity is destroyed. Kotlin Coroutines must run in an element, which is called a CoroutinesScope. A CoroutinesScope keeps track of your Coroutines, even Coroutines that are suspended. In other words, CoroutinesScope just only makes sure that you keep track them, and it cancel all all of the Coroutines started in it.
Kotlin协程中的作用域非常有用,因为我们必须在活动被销毁后立即取消后台任务。 Kotlin协程必须在一个称为CoroutinesScope的元素中运行。 CoroutinesScope会跟踪您的协程,甚至是已暂停的协程。 换句话说,CoroutinesScope仅确保您跟踪它们,并取消其中所有启动的所有Coroutines。
When we need to use the global scope, which is our application scope, not the activity scope, we can use the GlobalScope.
当我们需要使用全局范围(这是我们的应用程序范围,而不是活动范围)时,可以使用GlobalScope。
withContext (withContext)
withContext is an another way to write the async where we do not need to write await(). For example:
withContext是另一种无需编写await()的异步方法。 例如:
suspend fun fetchUser(): User { return withContext(Dispatchers.IO) {
// make network call
// return user
}
}
In conclusion, in fact, Kotlin Coroutines is a very efficient and complete framework to manage concurrency with simple, comprehensive, and robust approach. In this article some basic concepts of Kotlin Coroutines were considered for Android developers.
总之,实际上,Kotlin Coroutines是一个非常有效和完整的框架,可通过简单,全面和强大的方法来管理并发。 本文为Android开发人员考虑了Kotlin Coroutines的一些基本概念。
翻译自: https://medium.com/kayvan-kaseb/understanding-kotlin-coroutines-e0a4368339b0
协程 kotlin