Asynchronous programming in Android
Asynchronous programming in Android can be done in various ways. Two of them are:
1. Using callback
2. Using coroutines
Below is the example of using callback:
import kotlin.concurrent.thread | |
fun getUserFromAPI( | |
userId: String, | |
onUserAvailable: (User) -> Unit | |
) { | |
thread { | |
Thread.sleep(1000) | |
val user = User(userId, "user") | |
onUserAvailable(user) | |
} | |
println("end") | |
} | |
fun main1() { | |
getUserFromAPI("1") { user -> | |
println(user) | |
} | |
println("main end") | |
} | |
data class User(val userId: String, val username: String) |
Below is the example of using coroutine:
import kotlinx.coroutines.GlobalScope | |
import kotlinx.coroutines.delay | |
import kotlinx.coroutines.launch | |
data class User(val userId: String, val username: String) { | |
override fun toString(): String { | |
return userId + " " + username | |
} | |
} | |
suspend fun getUserSuspend(userId: String): User { | |
delay(1000) | |
return User(userId, "coroutine") | |
} | |
fun main() { | |
GlobalScope.launch { | |
val user = getUserSuspend("1") | |
println("user is:" + user) | |
} | |
Thread.sleep(2000) | |
} |
...
Note that suspend function can only be called either from a coroutine or from another suspend function.
Here GlobalScope implements CoroutineScope and launch is a coroutine builder which is an extension function of CoroutineScope.
Coroutine
A coroutine is an instance of suspendable computation. It is conceptually similar to a thread, in the sense that it takes a block of code to run that works concurrently with the rest of the code. However, a coroutine is not bound to any particular thread. It may suspend its execution in one thread and resume in another one.
Coroutines can be thought of as light-weight threads
// Sequentially executes doWorld followed by "Hello"
fun main() = runBlocking {
doWorld()
println("Done")
}
// Concurrently executes both sections
suspend fun doWorld() = coroutineScope { // this: CoroutineScope
launch {
delay(2000L)
println("World 2")
}
launch {
delay(1000L)
println("World 1")
}
println("Hello")
}
runBlocking and coroutineScope builders may look similar because they both wait for their body and all its children to complete. The main difference:
runBlocking method blocks the current thread for waiting,
coroutineScope just suspends, releasing the underlying thread for other usages.
Because of that difference, runBlocking is a regular function and coroutineScope is a suspending function.
Coroutine builder: launch, async => to use suspend function in normal function. Used to link normal function and suspending function.
Syntax of launch:
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {
---
}
Scoping function: coroutineScope, withContext
Comments
Post a Comment