preface
As Kotlin has blossomed, StackOverflow’s list of the most popular programming languages among developers has a whopping 72.6 percent support for Kotlin.
The Kotlin1.3 coroutine has been released, which means that language support and apis for coroutines have been fully stable since Kotlin1.3.
Coroutines profile
Official definition of coroutines
Coroutines simplify asynchronous programming by putting complexity into libraries. The program logic can be expressed sequentially in coroutines, and the underlying library takes care of the asynchrony for us. The library can wrap the relevant parts of user code as callbacks, subscribing to related events, and scheduling execution on different threads (or even different machines), while keeping the code as simple as sequential execution.
Advantages of coroutines over threads:
To create a new thread in Android, it takes about 1M memory. If you use thread pools, synchronizing data between threads is not a long and complicated thing, so we have coroutines:
- You can think of them as lightweight threads, and the cost of creating a coroutine is very low
- You can easily suspend and resume operations
- Coroutines that support blocking threads and coroutines that support non-blocking threads
- Asynchrony and concurrency are better implemented
Start a hundred thousand coroutines, and after one second each coroutine outputs a point. Now what happens if you try to do it using threads? (It is likely that your code will produce some sort of out-of-memory error.)
Import kotlinx.coroutines.* fun main() = runBlocking {repeat(100_000) {// Launch a large number of coroutines {delay(1000L)print(".")}}}Copy the code
In simple terms, asynchronous operations can be greatly simplified, programs can be expressed sequentially, and coroutines also provide a way to avoid blocking threads and replace it with a cheaper and more controllable operation – coroutine suspend.
Use of coroutines in Android
To use Kotlin coroutines in Android, you need to introduce the Kotlinx. coroutines library:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:x.x.x'// The kotlinx-Coroutines-Core and kotlin-stdlib libraries are introduced in the Android libraryCopy the code
Kotlin-stdlib: 1.2m libraries that must be imported for projects using Kotlin
Kotlinx coroutines — core: 1.5 M
Kotlinx coroutines – android: 21 k
So if we introduce the Kotlinx-Coroutines-Android library into the Android project we are currently developing using Kotlin, the project size will increase by about 1.5m, and by about 600K after generating APK
application
Common scenarios:
When a background thread executes a complex task, the next task depends on the results of the previous task, so it must wait for the previous task to complete before starting execution. Look at the three functions in the code below, the last two of which depend on the results of the previous one
fun requestToken(): Token {
// makes request for a token & waits
return token // returns result when received
}
fun createPost(token: Token, item: Item): Post {
// sends item to the server & waits
return post // returns resulting post
}
fun processPost(post: Post) {
// does some local processing of result
}
Copy the code
A common approach is to use callbacks to encapsulate tasks that need to be performed later as callbacks.
fun requestTokenAsync(cb: (Token) -> Unit) { ... }
fun createPostAsync(token: Token, item: Item, cb: (Post) -> Unit) { ... }
fun processPost(post: Post) { ... }
fun postItem(item: Item) {
requestTokenAsync { token ->
createPostAsync(token, item) { post ->
processPost(post)
}
}
Copy the code
Callbacks are very simple and useful in scenarios with only two tasks. Many network request frameworks use callback onSuccess Listeners, but in scenarios with more than three tasks, multiple layers of nested callbacks will occur and exceptions will not be easily handled.
Use the Kotlin coroutine
suspendfun requestToken(): Token { ... } // Suspend the functionsuspendfun createPost(token: Token, item: Item): Post { ... } // Suspend fun processPost(post: post) {... } fun postItem(item: Globalscope.launch {val token = requestToken() val post = createPost(token, Item) processPost(post) Try /catch}}Copy the code
The suspend keyword in coroutines has been officially supported by the Network request framework Retrofit in V2.6.0(2019-06-05)
@GET("users/{id}")
suspend fun user(@Path("id"Val User :User = api.getuser () val User :User = Api."id")
Copy the code
Ps: This paper only makes a simple introduction of coroutines. For specific use, please refer to official documents