<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Sibaprasad Mohanty on Medium]]></title>
        <description><![CDATA[Stories by Sibaprasad Mohanty on Medium]]></description>
        <link>https://medium.com/@sibaprasad.mohanty?source=rss-a7e5d4757ae1------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*2dqmOg58fepzS5nv</url>
            <title>Stories by Sibaprasad Mohanty on Medium</title>
            <link>https://medium.com/@sibaprasad.mohanty?source=rss-a7e5d4757ae1------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 27 May 2026 00:53:31 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@sibaprasad.mohanty/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Kotlin Co-routines]]></title>
            <link>https://medium.com/@sibaprasad.mohanty/kotlin-co-routines-12070db8d4ae?source=rss-a7e5d4757ae1------2</link>
            <guid isPermaLink="false">https://medium.com/p/12070db8d4ae</guid>
            <category><![CDATA[kotlin-coroutines]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[kotlin]]></category>
            <dc:creator><![CDATA[Sibaprasad Mohanty]]></dc:creator>
            <pubDate>Fri, 16 Jul 2021 09:11:26 GMT</pubDate>
            <atom:updated>2021-07-16T11:11:07.269Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>COROUTINES</strong><br>•Coroutines is an instance of suspendible computation<br>•It is similar to thread but its light weight than thread<br>•coroutine is not bound to any particular thread. It may suspend its execution in one thread and resume in another one.</p><blockquote><strong>First Coroutines example</strong></blockquote><blockquote>fun main() = runBlocking { // this: CoroutineScope<br> launch { // launch a new coroutine and continue<br> delay(1000L) // non-blocking delay for 1 second (default time unit is ms)<br> println(“World!”) // print after delay<br> }<br> println(“Hello”) // main coroutine continues while a previous one is delayed<br>}</blockquote><p><strong>It will print</strong><br>Hello<br>World!</p><h4>Let us discuss the keywords used here to create coroutines<br>1. launch()</h4><ul><li>is a coroutine builder.</li><li>is a coroutine builder.</li><li>It launches a new coroutine concurrently with the rest of the code, which</li><li>continues to work independently.</li><li>That’s why Hello has been printed first.</li><li>delay is a special suspending function.</li><li>It suspends the coroutine for a specific time.</li><li>Suspending a coroutine does not block the underlying thread, but allows other coroutines to run and use the underlying thread for their code.</li></ul><p><strong>2. runBlocking() </strong><br>1. is also a coroutine builder that bridges the non-coroutine world of a regular fun main() and the code with coroutines inside of runBlocking { … } curly braces</p><p>2. This is highlighted in an IDE by this: CoroutineScope hint right after the runBlocking opening curly brace.<br>3. If you remove or forget runBlocking in this code, you’ll get an error on the launch call, since launch is declared only in the CoroutineScope:<br>Unresolved reference: launch.</p><h3>COROUTINES</h3><ul><li>Coroutine Concept</li><li>Scope</li><li>suspending functions</li><li>Jobs</li><li>Context</li><li>Exception Handling</li></ul><h4>Use of Coroutines</h4><ul><li>Threads are resource intensive — it need resource to start stop</li><li>Coroutines are lightweight threads and uses thread pools</li><li>Simplify async code, callbacks and synchronisation</li><li>Simple syntax</li><li>Can pause and resume at any time, On a number of thread</li></ul><p><strong>Scope</strong> <em>Create and run coroutines, provides life cycle events</em><br><strong>Context</strong> <em>The scope provides a context in which the coroutine runs</em><br><strong>Suspending function </strong><em>Functions that can be run in a coroutines</em><br><strong>Jobs</strong> handle on coroutines<br><strong>Deferred</strong> a future result of a coroutine<br><strong>Dispatcher</strong> manages which thread(s) the coroutine runs on<br><strong>Error handling</strong></p><p>1. <strong>runBlocking</strong><br>2. <strong>launch</strong><br>3. <strong>GlobalScope</strong><br>4. <strong>repeat</strong></p><p><strong>Scope</strong><br>- It provides lifecycle methods for coroutines<br>- Allows us to start and stop coroutines<br>- <strong>GlobalScope.launch{}</strong> The scope of the coroutine is the lifecycle of entire application<br>- <strong>runBlocking</strong> Creates a scope and runs coroutines in a blocking way<br>- <strong>coroutineScope</strong> Creates a new scope does not complete until a children coroutines is complete</p><pre>runBlocking{<br> launch{<br> delay(1000L)<br> println(“Hello”)<br> }<br>}</pre><pre>GlobalScope.launch{<br> delay(1000L)<br> println(“Hello”)<br>}</pre><pre>coroutineScope{<br> delay(1000L)<br> println(“Custom coroutinesScope”)<br>}</pre><p>Context<br>- A context is a set of data relates to coroutines<br>- All coroutines have an associated context<br>- You can start and stop coroutines<br>- But context is the data associated with coroutines<br>- Important elements of context<br>- 1. Dispatcher — Which thread the coroutines is run on<br>- 2. Job — Handle on the coroutine lifecycle<br>- If you explore GlobalScope, you can see coroutineScope and its use inside it</p><p>Suspending Function<br>- A function that can be run in a coroutine<br>- Make callbacks seamless</p><pre>suspend fun sayHello(){<br> print(“”Hello)<br>}</pre><pre>GlobalScope.launch{<br> sayHello()<br>}</pre><p><strong>Jobs</strong><br>- A .launch() call returns a job<br>- Allows us to manipulate the coroutine lifecycle<br>- Live in the hierarchy of other jobs both as parents or children</p><pre>job{<br> job{}<br>job{<br> job{} <br>} <br>}</pre><pre>val job1 = GlobalScope.launch{<br> coroutineScope{<br> val job2 = launch{<br> // processing<br> }<br> }<br> }</pre><p>- Can access lifecycle variables and methods<br>- cancel()<br>- join()<br>- If a job is cancelled, all it’s parents and children will be cancelled too.</p><p><strong>Dispatchers</strong><br>- A dispatcher determines which thread or thread pool the coroutine runs on<br>- Different dispatchers are available depending on the task specificity</p><pre>launch(Dispatchers.Default){<br> // do some cpu intensive processing task here<br>}</pre><h4>Common Dispatchers</h4><p><strong>1. Main</strong><br>- Main thread update in UI driven applicaiton(eg Android)<br>- Main dispatcher needs to be defined in grade<br><strong>2. Default</strong><br>- Useful for CPU intensive work<br><strong>IO</strong><br>- useful for network communication or reading or writing files<br><strong>Unconfined</strong><br>- Starts the coroutine in the inherited dispatcher that called it<br><strong>newSingleThreadContext(“”MyThread)</strong><br>- Forces creation of a new thread<br>- This is not used more often, because it more expensive and heavy</p><p><strong>Async</strong><br>- Another way to start a coroutines<br>- Just like launch, except it returns a result<br>- In the form of a deferred<br>- Deferred — a future promise of a returned value<br>- When we need the value, we call await() (blocking call)`<br>- If the value is available, it will return immediately<br>- If the value is not available, it will pause the thread until it is</p><pre>suspend function getRandom() = Random.nextINt(1000)</pre><pre>val valueDeffered = GlobalScope.async{<br> getRandom()<br>}<br>// DO ome processing here<br>val finalValue = valueDeffered(<br>```</pre><p><strong>withContext</strong><br>- Allows us to easily change context<br>- Easily switch between dispatchers<br>- very Lightweight</p><pre>launch(Dispatchers.Default){<br> // default context<br>withCOntext(Dispatcher.IO){<br> // IO context <br>}<br>// back to default context<br>}</pre><p><strong>Exception Handling in Coroutines</strong><br>-Exception behaviour depends on the coroutines builder<br><strong>launch</strong><br>- Propagates through the parent-child hierarchy<br>- The exception will be thrown immediately and jobs will fail<br>- use try-catch or an exception handler<br> <br><strong>async</strong><br>- Exceptions are deferred until the result is consumed<br>- If the result is not consumed, the exception is never thrown<br>- try-catch in the coroutine or in the await() cal</p><pre>val myHandler = CoroutineExceptionHandler { coroutineCOntext, throwable -&gt;<br> // handle exception<br>}</pre><pre>launch(myHandler){<br> // do some task here<br> throws IndexOutOfBoundException()<br>}<br>```<br>- If we want to pass Coroutine handler and also a Dispatcher then we can use like this<br>```<br>launch(Dispatchers.Default + myHandler){<br> // do some task here<br> throw IndexOutOfBoundException()<br>}</pre><p><strong>Sample Android Application for coroutines</strong><br>- Objectives<br>- Get an image from a URL<br>- Apply processing<br>- Show it in an ImageView</p><ul><li>In this example we will create a CoroutineScope with using scope = main, because we have to update the image in main thread</li></ul><pre>private val coroutineScope = CoroutineScope(Dispatchers.Main)</pre><pre>coroutineScope.launch {<br> val originalDeferred = coroutineScope.async(Dispatchers.IO) { getOriginalBitmap() } // This will download the image bitmap from the url</pre><pre>val originalBitmap = originalDeferred.await() // By calling this, it will wait until the result not getting</pre><pre>val filteredDeferred = coroutineScope.async(Dispatchers.Default) { applyFilter(originalBitmap) } // another background task to apply the filter</pre><pre>val filteredBitmap = filteredDeferred.await() // in this line it will execute</pre><pre>loadImage(filteredBitmap) // in this it will load the image to the Image view in the main thread<br>}</pre><p><a href="https://github.com/spdobest/CoroutinesWorld/tree/master/ImageProcessingCoroutines">Click here for Basic Example here</a><br><strong>Another Example to use Coroutines with Retrofit in MVVM pattern</strong><br>- Get a list of country info from an endpoint<br>- Use coroutines with Retrofit and MVVM<br>- Show it in a RecyclerView<br>- <a href="https://github.com/spdobest/CoroutinesWorld/tree/master/AndroidCoroutinesRetrofit">Click here for Retrofit with Coroutines Example</a></p><p><strong>Coroutines, Room, MVVM</strong><br>- Objective of this project<br>- Create, Read and delete data in a Room Database.<br>- Use coroutines with Room and MVVM<br>- Navigate in an app based on that data<br>-<a href="https://github.com/spdobest/CoroutinesWorld/tree/master/CoroutinesRoom"> Click here for Room databse with Coroutines Example</a><br>- IN this example we have used coroutines with Room database<br>- Initialize Coroutine scope</p><pre>private val coroutineScope = CoroutineScope(Dispatchers.IO)<br>private val db by lazy { UserDatabase(getApplication()).userDao() }</pre><p>- Now do the operation inside coroutine scope</p><pre>coroutineScope.launch {<br> val user = db.getUser(username)<br> if(user != null) {<br>         withContext(Dispatchers.Main) {<br>             error.value = “User already exists”<br>          }<br> } else {<br>         val user = User(username, password.hashCode(), info)<br>         val userId = db.insertUser(user)<br>         user.id = userId<br>         LoginState.login(user)</pre><pre>withContext(Dispatchers.Main) {<br>         signupComplete.value = true<br>      }<br>   }<br>}</pre><p><strong>Asynchronous Flow</strong><br>- What is Asynchronous Flow<br>- Creating flows<br>- Properties<br>- Operators<br>- Buffering<br>- Composing flows<br>- Exception handling</p><p><strong>Asynchronous Flow</strong><br>- Flows emits value<br>- Some other coroutines to collect the emitted values<br>- A flow is a stream of values that are Asynchronously computed<br>- <strong>flow{…}</strong> — It’s a builder. It will transfer the value<br>- <strong>emit(value) </strong>— Transmit a value<br>- <strong>collect{…}</strong> — Receive the values. Until the collect method is not called it will not emmit the value</p><pre>fun sendPrimes(): Flow&lt;Int&gt; = flow{<br> val primeNumbers = listOf(2,3,5,7,11,13,17,19,23,29)<br> primeNumbers.forEach {<br> kotlinx.coroutines.delay(it*100L)<br> emit(it)<br> }<br>}</pre><ul><li>We can call the flow method like this</li></ul><pre>sendPrimes().collect {<br>     println(“Received prime numnbers $it”)<br>}</pre><p><strong>Creating flow</strong><br>- There different way to create a flow<br>- 1. Generate flow by emitting each value</p><pre>fun sendNumbers() = flow {<br>    for(i in 1..10){<br>       emit(i)<br>    } <br>}</pre><p><strong>using .asFlow()</strong><br>- A collection can be converted directly into a flow using collection.asFlow() function</p><pre>fun sendNumbers() = listOf(1,2,3,4,5).asFLow()</pre><p><strong>flowOf(T)</strong><br>- We can create flow using **flowOf** function<br>- A flow can be generated from a number of parameters of any Type<br>```<br> fun sendNumbers() = flowOf(“One”, “Two”, “Three”)<br>```<br><strong> Flow Properties</strong><br>- Cold<br> — Flows are cold<br> — The code does not run until the **collect** function is called<br>- <strong>Cancelation</strong><br> — Flows cant be cancelled by itself<br> — It will be cancelled when the encompassing coroutine is cancelled<br> — Flow is transparent for cancellation</p><pre>fun sendNumbersTOCheckCancellation() : Flow&lt;Int&gt; = flow{<br> val list = listOf(1, 2, 3)<br> list.forEach {<br>      kotlinx.coroutines.delay(100L)<br>      emit(it)<br> }<br>}</pre><pre>runBlocking {<br> val numbersFlow = sendNumbersTOCheckCancellation()<br>      println(“FLow has not started yet”)<br>      println(“Started Flow now”)<br>      withTimeoutOrNull(1000){<br>        numbersFlow.collect {<br>           println(it)<br>       }<br>     }<br>   }</pre><p>- As per the above code it will print each number with 400 mlliseconds delay<br>- But it will cancel the flow after 1000 milliseconds defined <strong>withTimeoutOrNull</strong>(1000)<br>- We can cancelling the coroutine after 1000 milliseconds, so the flow will cancel<br><strong>Operator</strong><br>- It take an input flow, transform it and return an output flow<br>- Operators are cold<br>- The returning flow is synchronous<br>- **You can find all the operator by putting a dot after a flow</p><p><strong>(1..10).asFlow()</strong><br>- List of all the operators<br>- also<br>- apply<br>- let<br>- run<br>- runCatching<br>- takeIf<br>- take<br>- takeUnless<br>- reduce<br>- transform<br>- map<br>- broadcastIn<br>- buffer<br>- cancellable<br>- catch<br>- collectIndexed<br>- collectLatest<br>- combine<br>- combineTransform<br>- conflate<br>- count<br>- debounce<br>- filter<br>- filterNot<br>- first<br>- firstOrNull<br>- flatMapConcat<br>- flatMapMerge<br>- flatMapLatest<br>- fold<br>- launchIn<br>- mapLatest<br>- mapNotNull<br>- onCompletion<br>- onEach<br>- onEmpty<br>- onStart<br>- retry<br>- retryWhen<br>- runningReduce<br>- sample<br>- scan<br>- single<br>- singleOrNull<br>- takeWhile<br>- toCollection<br>- toList<br>- transformLatest<br>- transformWhile<br>- withIndex<br>- zip<br>- filterNotNull<br><strong>1. Map</strong></p><pre>suspend fun mapOperator(){<br> (1..10).asFlow()<br> .map {<br> delay(500L)<br> “Mapping $it”<br> }<br> .collect {<br> println(it)<br> }<br>}</pre><p><strong>2. Filter</strong></p><pre>suspend fun filterOperator(){<br> (1..10).asFlow()<br> .filter { <br>    it%2 == 0<br> }<br> .collect {<br>     println(it)<br>  }<br>}</pre><p><strong>3. transform </strong><br>- General transformation operator<br>- Can emit any value at any point</p><pre>suspend fun transformOperator(){<br> (1..10).asFlow()<br> .transform {<br> emit(“Emitting string value $it”)<br> emit(it)<br> }<br> .collect {<br> println(it)<br> }<br>}</pre><p><strong>4. Take</strong><br>- Use only a number of values, disregard the rest</p><pre>(1..10).asFLow(<br>.take(2)<br>.colect{<br> println(it)<br>}<br>```<br>- Above code only first 2 values</pre><p><strong>Terminal flow</strong><br>- There are few operators to convert the flow into a collection<br>- collect<br>- toList<br>- toSet<br>- reduce<br><strong>reduce</strong></p><pre>suspend fun reduceOperator(){<br> val size = 10<br> val factorial = (1..size).asFlow()<br> .reduce { accumulator, value -&gt;<br> accumulator * value<br> }<br> println(“Factorial of $size is $factorial”)<br>}</pre><p><strong>flowOn</strong><br>- Change the context on which the flow is emitted</p><p><strong>buffer</strong><br>- In case of processing a flow takes a long time<br>- a buffer is useful to accumulate flow values that can be processed later<br>```<br>fun generate(): Flow&lt;Int&gt; = flow{<br> for(i in 1..3){<br> delay(100)<br> emit(i)<br> }<br>}</p><p>val time = measureTimeMillis {<br> generate()<br> .reduce()<br> .collect {<br> delay(300)<br> println(it)<br> }<br>}<br>println(“Collected in $time ms”)<br>```<br><strong>Composing Flow</strong><br>- If there are multiple flows and you want to combine those flows, then we can use the below operators<br><strong>1. zip</strong><br>- It will compose the value emitted by 2 flows<br>```<br>suspend fun zipExample(){<br> val english = flowOf(“One”, “Two”, “Three”)<br> val hindi = flowOf(“ek”, “do”, “teen”)<br> english.zip(hindi) { a,b -&gt; “‘$a in Hindi is $b’”}<br> .collect {<br> println(it)<br> }</p><p>}<br>```<br><strong>Combine</strong><br>- Combine the latest value of one flow with the latest value of other</p><p>## EXception Handling<br>- SImply use try catch block to handle exception<br>```<br>try{<br> (1..3).asFlow()<br> .onEach{ check(it != 2) }<br> .collect{ println(it) }<br>}<br>catch(e:Exception){<br> println(“Caught exception”)<br>}<br>```<br>### .catch() method in flow<br>```<br> (1..3).asFlow()<br> .onEach{ check(it != 2) }<br> .catch{ e -&gt; println(“Caught Exception $e”) }<br> .collect{ println(it) }<br>```<br>### onCompletion block<br>- Its same as final block<br>```<br> (1..3).asFlow()<br> .onEach{ check(it != 2) }<br> .onCOmpletion{ cause -&gt;<br> if(cause != null)<br> println(“Flow Completed with $cause”) <br> else<br> println(“Flow Completed Successfully”)<br> }<br> .catch{ e -&gt; println(“Caught Exception $e”) }<br> .collect{ println(it) }<br>```</p><h4>Android application using flow</h4><p>— Coroutines flow<br>- Retrofit<br>- MVVM<br>- <a href="https://github.com/spdobest/CoroutinesWorld/tree/master/AndroidCoroutinesFlow">Click here for Coroutines flow with Retrofit and MVVM</a><br>- Use coroutines flow to update an interface<br>- Use coroutines flow with Retrofit &amp; MVVM<br>- Show news items periodically in a list</p><h3>Channels</h3><p>- Channel Producer<br>- Pipelines<br>- Fan-out<br>- Fan-in<br>- Buffered Channels<br>- Ticker channels</p><p><strong>Channels</strong><br>- A channel is a queue of data<br>- A coroutine can asynchronously put elements .send(data)<br>- Another can blockingly get elements .receive()<br>- A channel is closed when there are no more elements .close()<br>```<br>val channels = Channel&lt;Int&gt;()<br>launch {<br> for(x in 1..5)<br> channels.send(x * x)<br>}<br>for(i in 1..5)<br> println(channel.receive())<br>```<br>- Another Way<br>```<br>val channels = Channel&lt;Int&gt;()<br> launch {<br> for(x in 1..5)<br> channels.send(x * x)<br> channels.close()<br> }<br>for(i in channels)<br> println(i)<br>```<br>## Channel Produceer<br>- Allows a data source to create and return a channel<br>- CoroutineScope.produce{…}<br>- Need a coroutine scope to run the code<br>```<br>val channel = produce {<br> for(x in 1..5){<br> send(<br> }<br>}<br>```<br>## Pipelines<br>- A pipeline is a development pattern<br>- where one channel output is given an input to another channel<br>- One coroutine is producing a(potentially infinite) set of values, one or more coroutines are consuming and transforming those values.<br>```<br>fun CoroutineScope.produceNumbers() = Produce&lt;Int&gt;{<br> var x = 1<br> while(true)<br> send(x++)<br>}</p><p>fun CoroutineScope.square(numbers: ReceiveChannel&lt;Int&gt;){<br> for(x in numbers){<br> send(x*x)<br> }<br>}</p><p>val numbers = produceNumbers()<br>val swuares = square(numbers)<br>for(i in 1..5){<br> println(squares.receive())<br>}<br>println(“Done”)<br>coroutineContext.cancelChildren()<br>``` <br>## Fan-out<br>- If multiple coroutines receive from the same channel values(work) are distributed among them<br>```<br>fun CoroutineScope.produceNumbers() = produce&lt;Int&gt;{<br> var x = 1<br> while(true){<br> send(x++)<br> delay(100L)<br> }<br>}</p><p>fun CoroutineScope.launchProcessor(id: Int, channel: ReceiveChannel&lt;Int&gt;) = launch {<br> for(msg in channel){<br> println(“processor #$id received $msg”)<br> }<br>}</p><p>val processor = produceNumbers()<br>repeat(5) { launchProcessor(it, producer) }<br>delay(500)<br>producer.cancel()<br>```<br>## fan-in<br>- It’s opposite of fan out<br>- Multiple coroutines send values to one channel<br>```<br>suspend fun sendString(channel: SendChannel&lt;String&gt;, s: String, time: Long){<br> while(true){<br> delay(time)<br> channel.send(s)<br> }<br>}</p><p>val channel = Channel&lt;String&gt;()<br>launch{ sendString(channel, “message1”, 2000L) }<br>launch{ sendString(channel, “message1”, 2000L) }<br>repeat(6) { println(channel.receive()) }<br>coroutineCOntext.cancelChildern()<br>```<br>## Buffered Channel<br>- A Buffered channel has a limited capacity<br>- when the capacity is reached, the sender is paused<br>- when capacity becomes available new values can be sent<br>```</p><p>```<br>## Ticker Channels<br>- Periodically produces a unit after a given delay.<br>- Has an Optional initial delay<br>```<br>val tickerChannel = ticker(delaysMillis = 100, initialDelaysMillis = 0)<br>launch {<br> val startTime = System.currentTimeMillis()<br> tickerChannel.consumeEach{<br> val delta = System.currentTimeMillis() — startTime<br> println(“Received tick after $delta”)<br> }<br>}<br>delay(1000)<br>println(“Done”)<br>tickerChannel.cancel()<br>```<br>## Coroutine Concurrency and shared state</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=12070db8d4ae" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>