Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin Coroutines 101

Kotlin Coroutines 101

As the title suggests this is a complete 101 guide to Kotlin coroutine. The talk will cover the basics of coroutines and how to get started with them. We will look at how to incorporate coroutines in your applications. We will also look at why coroutines are better for asynchronous programming and what other solutions exist today for achieving async and their pain-points.

Sagar Viradiya

August 24, 2019
Tweet

More Decks by Sagar Viradiya

Other Decks in Programming

Transcript

  1. What is Coroutine? 1. Coroutines are like lightweight threads. 2.

    Allows to write async code in sequential manner.
  2. fun getToken(cb: (Token) -> Unit) { //Makes a request for

    token, invokes callback when done //returns immediately } fun getTweets(token: Token, cb: (List<Tweet>) -> Unit) { //Makes a request for tweets, invokes callback when done //returns immediately }
  3. Callback Display list of tweets 1. Get token 2. Get

    list of tweets 3. Process tweets
  4. fun getToken(cb: (Token) -> Unit) { //Makes a request for

    token, invokes callback when done //returns immediately } fun getTweets(token: Token, cb: (List<Tweet>) -> Unit) { //Makes a request for tweets, invokes callback when done //returns immediately } fun processTweets(tweets: List<Tweet>, cb: (List<Tweet>) -> Unit) { //Process list of tweet, invoke callback when done //returns immediately }
  5. fun displayTweets() { getToken { token -> getTweets(token) { tweets

    -> processTweets(tweets) { tweets -> //Consume tweets } } } }
  6. Reactive programming fun displayTweets() { val disposable = getToken() .flatMap(token:

    Token) { return getTweets(token) } .map(tweets: List<Tweet>) { //Perform processing } .subscribe( tweets -> { //Consume tweets }, throwable -> { //Handle error } ) }
  7. Coroutines way to Async suspend fun getToken(): Token { //Get

    token from n/w call return token } suspend fun getTweet(token: Token): List<Tweet> { //Get tweets using token from n/w call return tweets } suspend fun processTweet(tweets: List<Tweet>): List<Tweet> { //Perform processing on list return updatedTweets }
  8. suspend fun displayTweets() { val token = getToken() val tweets

    = getTweets(token) val updatedTweets = processTweets(tweets) //Consume updatedTweets }
  9. Coroutines 1. Coroutines are like light weight threads. 2. It

    allows you to write async code in sequential manner.
  10. fun main() = runBlocking { repeat(100_000) { // launch a

    lot of coroutines launch { delay(1000L) print(".") } } }
  11. suspend fun displayTweets() { val token = getToken() val tweets

    = getTweets(token) val updatedTweets = processTweets(tweets) //Consume updatedTweets }
  12. ync suspend fun getToken(): Token { //Get token from n/w

    call return token } suspend fun getTweet(token: Token): List<Tweet> { //Get tweets using token from n/w call return tweets } suspend fun processTweet(tweets: List<Tweet>): List<Tweet> { //Perform processing on list return updatedTweets }
  13. Concept of continuation void getToken(Continuation<Token> continuation) { //Get token from

    n/w call continuation.resume(token) } void getTweets(Token token, Continuation<List<Tweet>> continuation) { //Get tweets using token from n/w call continuation.resume(tweets) } void processTweets(List<Tweet> tweets, Continuation<List<Tweet>> continuation) { //Perform processing on list continuation.resume(updatedTweets) }
  14. GlobalScope.launch { // launch new coroutine in background and continue

    delay(1000L) // non-blocking delay for 1 second (default time unit is ms) println("Hello World!") // print after delay }
  15. class MainActivity : AppCompatActivity(), CoroutineScope { private lateinit var job:

    Job override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) job = Job() runTask() ... } fun runTask() { launch { //Perform task here } } override fun onDestroy() { job.cancel() super.onDestroy() } }
  16. Launch fun CoroutineScope.launch( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart =

    CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> Unit ): Job
  17. Launch val job = GlobalScope.launch { // launch new coroutine

    in background and continue delay(1000L) // non-blocking delay for 1 second (default time unit is ms) println("Hello World!") // print after delay } . . . job.cancel()
  18. Async - Await Use for concurrent tasks which are independent

    of each other. Await - Suspending function to get result from async.
  19. Async fun <T> CoroutineScope.async( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart

    = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> T ): Deferred<T>
  20. suspend fun displayTweets() { val token = getToken() val tweets1

    : Deferred<List<Tweet>> = async(Dispatchers.Default) { getTweets(token, "#IPL") } val tweets2 : Deferred<List<Tweet>> = async(Dispatchers.Default) { getTweets(token, "#EPL") } val updatedTweets = processTweets(tweets1.await() + tweets2.await()) //Consume updatedTweets }
  21. fun main() = runBlocking<Unit> { // start main coroutine GlobalScope.launch

    { // launch new coroutine in background and continue delay(1000L) println("World!") } println("Hello,") // main coroutine continues here immediately }
  22. coroutineScope Designed for parallel decomposition of work. suspend fun doThingsParallelly()

    = coroutineScope { val result1 = async { //Task1 } val result2 = async { //Task2 } result1.await() + result2.await() }
  23. withContext Mostly for thread switching. launch { mainScope -> .

    . . val result = withContext(Dispatcher.Default) { //Perform heavy task here } . . . }
  24. Summary 1. Need for async programming. 2. Ways to achieve

    async programming. 3. Suspending functions. 4. Coroutines scope. 5. Coroutines context. 6. Coroutines builders. 7. Coroutines dispatchers. 8. Scoping functions.
  25. Resources Kotlin official doc - https://kotlinlang.org/docs/reference/coroutines/basics.html Blog post - https://antonioleiva.com/coroutines/

    Videos • KotlinConf 2018 - Exploring Coroutines in Kotlin by Venkat Subramariam https://youtu.be/jT2gHPQ4Z1Q • KotlinConf 2017 - Introduction to Coroutines by Roman Elizarov https://youtu.be/_hfBv0a09Jc • KotlinConf 2018 - Android Suspenders by Chris Banes https://youtu.be/P7ov_r1JZ1g