<?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"><channel><title><![CDATA[Master kotlin]]></title><description><![CDATA[Master kotlin]]></description><link>https://masterkotlin.com</link><generator>RSS for Node</generator><lastBuildDate>Thu, 08 Oct 2026 10:15:50 GMT</lastBuildDate><atom:link href="https://masterkotlin.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Kotlin Coroutines Demystified]]></title><description><![CDATA[The Complete Practical Guide Every Kotlin Developer Should Read
When I first started using Coroutines, I thought I understood them.
I could write:
viewModelScope.launch {
    val users = repository.ge]]></description><link>https://masterkotlin.com/kotlin-coroutines-demystified</link><guid isPermaLink="true">https://masterkotlin.com/kotlin-coroutines-demystified</guid><category><![CDATA[coroutines]]></category><category><![CDATA[Kotlin]]></category><category><![CDATA[Android]]></category><dc:creator><![CDATA[Abhishek Kumar]]></dc:creator><pubDate>Wed, 08 Jun 2022 04:45:29 GMT</pubDate><content:encoded><![CDATA[<h2>The Complete Practical Guide Every Kotlin Developer Should Read</h2>
<p>When I first started using Coroutines, I thought I understood them.</p>
<p>I could write:</p>
<pre><code class="language-kotlin">viewModelScope.launch {
    val users = repository.getUsers()
    updateUi(users)
}
</code></pre>
<p>The code worked. The UI was smooth.</p>
<p>Then a production bug appeared. A cancelled screen was still making network calls and a loading spinner never stopped.</p>
<p>That was the moment I realized:</p>
<blockquote>
<p>Knowing coroutine syntax is not the same as understanding coroutines.</p>
</blockquote>
<p>Coroutines are one of the most powerful features in Kotlin, but they are also one of the most misunderstood. This guide covers the fundamentals, internals, best practices, pitfalls, and real-world usage.</p>
<hr />
<h2>Why Coroutines Exist</h2>
<p>Before Coroutines, asynchronous programming often involved:</p>
<ul>
<li>Threads</li>
<li>Executors</li>
<li>Futures</li>
<li>Callbacks</li>
<li>CompletableFutures</li>
</ul>
<p>As projects grew, callback chains became difficult to maintain.</p>
<p>Coroutines were introduced to provide asynchronous programming with code that reads like synchronous code.</p>
<hr />
<h2>What Is a Coroutine?</h2>
<p>A common definition is:</p>
<blockquote>
<p>Coroutines are lightweight threads.</p>
</blockquote>
<p>A more accurate definition is:</p>
<blockquote>
<p>A coroutine is a unit of work that can suspend and resume without blocking a thread.</p>
</blockquote>
<p>Example:</p>
<pre><code class="language-kotlin">suspend fun fetchUser() {
    delay(1000)
}
</code></pre>
<p><code>delay()</code> suspends the coroutine and frees the thread for other work.</p>
<hr />
<h2>How Coroutines Work Under the Hood</h2>
<p>The Kotlin compiler converts suspend functions into state machines.</p>
<p>When suspension occurs:</p>
<ol>
<li>Current state is saved.</li>
<li>Execution pauses.</li>
<li>Thread becomes available.</li>
<li>Coroutine resumes later from the saved state.</li>
</ol>
<p>This is the primary reason coroutines scale efficiently.</p>
<hr />
<h2>suspend Does Not Start a Coroutine</h2>
<pre><code class="language-kotlin">suspend fun getUser()
</code></pre>
<p>A suspend function only indicates that suspension may occur.</p>
<p>Coroutines are started using builders such as:</p>
<pre><code class="language-kotlin">launch {}
async {}
runBlocking {}
</code></pre>
<hr />
<h2>launch vs async</h2>
<h3>launch</h3>
<p>Use when no result is required.</p>
<pre><code class="language-kotlin">launch {
    syncUsers()
}
</code></pre>
<p>Returns:</p>
<pre><code class="language-kotlin">Job
</code></pre>
<h3>async</h3>
<p>Use when a result is needed.</p>
<pre><code class="language-kotlin">val user = async {
    getUser()
}

user.await()
</code></pre>
<p>Returns:</p>
<pre><code class="language-kotlin">Deferred&lt;T&gt;
</code></pre>
<hr />
<h2>Parallel Execution Example</h2>
<pre><code class="language-kotlin">coroutineScope {
    val user = async { getUser() }
    val posts = async { getPosts() }

    user.await()
    posts.await()
}
</code></pre>
<p>A common use case is loading profile data and dashboard data together.</p>
<hr />
<h2>CoroutineContext</h2>
<p>Every coroutine contains context information.</p>
<pre><code class="language-kotlin">launch(
    Dispatchers.IO +
    CoroutineName("UserSync")
) {
}
</code></pre>
<p>Typically includes:</p>
<ul>
<li>Dispatcher</li>
<li>Job</li>
<li>CoroutineName</li>
<li>CoroutineExceptionHandler</li>
</ul>
<hr />
<h2>Dispatchers Explained</h2>
<h3>Dispatchers.Main</h3>
<p>For UI updates.</p>
<pre><code class="language-kotlin">withContext(Dispatchers.Main) {
    renderUi()
}
</code></pre>
<h3>Dispatchers.IO</h3>
<p>For network, file and database operations.</p>
<pre><code class="language-kotlin">withContext(Dispatchers.IO) {
    api.getUsers()
}
</code></pre>
<h3>Dispatchers.Default</h3>
<p>For CPU-intensive operations.</p>
<pre><code class="language-kotlin">withContext(Dispatchers.Default) {
    calculateReport()
}
</code></pre>
<h3>Tricky Point</h3>
<p>Don't run CPU-heavy work on IO.</p>
<p>Rule:</p>
<pre><code class="language-text">Waiting -&gt; IO
Computing -&gt; Default
</code></pre>
<hr />
<h2>Structured Concurrency</h2>
<p>One of the biggest advantages of coroutines.</p>
<pre><code class="language-kotlin">coroutineScope {
    launch { fetchUsers() }
    launch { fetchOrders() }
}
</code></pre>
<p>Benefits:</p>
<ul>
<li>Children belong to a parent scope.</li>
<li>Parent waits for children.</li>
<li>Failures propagate predictably.</li>
<li>Reduces leaks.</li>
</ul>
<hr />
<h2>GlobalScope: A Common Mistake</h2>
<p>Avoid:</p>
<pre><code class="language-kotlin">GlobalScope.launch {
    syncUsers()
}
</code></pre>
<p>Problems:</p>
<ul>
<li>No lifecycle awareness</li>
<li>Hard cancellation</li>
<li>Debugging issues</li>
<li>Memory leak risk</li>
</ul>
<p>Use:</p>
<pre><code class="language-kotlin">viewModelScope
lifecycleScope
</code></pre>
<hr />
<h2>Cancellation Is Cooperative</h2>
<p>Bad:</p>
<pre><code class="language-kotlin">while(true) {
}
</code></pre>
<p>Good:</p>
<pre><code class="language-kotlin">while(isActive) {
}
</code></pre>
<p>Another good practice:</p>
<pre><code class="language-kotlin">ensureActive()
</code></pre>
<hr />
<h2>Blocking vs Suspending</h2>
<p>Bad:</p>
<pre><code class="language-kotlin">Thread.sleep(5000)
</code></pre>
<p>Good:</p>
<pre><code class="language-kotlin">delay(5000)
</code></pre>
<p><code>Thread.sleep()</code> blocks threads.</p>
<p><code>delay()</code> suspends coroutines.</p>
<hr />
<h2>Exception Handling</h2>
<pre><code class="language-kotlin">val handler = CoroutineExceptionHandler { _, throwable -&gt;
    println(throwable.message)
}
</code></pre>
<p>Use it for top-level coroutine exception handling.</p>
<hr />
<h2>SupervisorJob</h2>
<p>Scenario:</p>
<ul>
<li>Load profile</li>
<li>Load notifications</li>
<li>Load messages</li>
</ul>
<p>If notifications fail, profile should still load.</p>
<pre><code class="language-kotlin">val scope = CoroutineScope(
    SupervisorJob() + Dispatchers.IO
)
</code></pre>
<p>This isolates failures.</p>
<hr />
<h2>Flow</h2>
<p>Flow is designed for streams of values.</p>
<pre><code class="language-kotlin">flow {
    emit(1)
    emit(2)
    emit(3)
}
</code></pre>
<p>Collect values:</p>
<pre><code class="language-kotlin">flow.collect {
    println(it)
}
</code></pre>
<hr />
<h2>StateFlow vs SharedFlow</h2>
<h3>StateFlow</h3>
<p>Best for UI state.</p>
<pre><code class="language-kotlin">MutableStateFlow(UiState())
</code></pre>
<p>Examples:</p>
<ul>
<li>Loading</li>
<li>Success</li>
<li>Error</li>
</ul>
<h3>SharedFlow</h3>
<p>Best for one-time events.</p>
<pre><code class="language-kotlin">MutableSharedFlow&lt;Event&gt;()
</code></pre>
<p>Examples:</p>
<ul>
<li>Toast</li>
<li>Navigation</li>
<li>Dialog events</li>
</ul>
<h3>Tricky Point</h3>
<p>Avoid using StateFlow for navigation events because they can be replayed after configuration changes.</p>
<hr />
<h2>Useful Flow Operators</h2>
<h3>map</h3>
<pre><code class="language-kotlin">flow.map { it.name }
</code></pre>
<h3>filter</h3>
<pre><code class="language-kotlin">flow.filter { it.isActive }
</code></pre>
<h3>debounce</h3>
<pre><code class="language-kotlin">searchQuery.debounce(500)
</code></pre>
<p>Useful for search APIs.</p>
<h3>combine</h3>
<pre><code class="language-kotlin">combine(userFlow, settingsFlow) { user, settings -&gt;
    Ui(user, settings)
}
</code></pre>
<hr />
<h2>Flow vs Channel</h2>
<h3>Flow</h3>
<p>Best for stream processing.</p>
<pre><code class="language-kotlin">Flow&lt;User&gt;
</code></pre>
<h3>Channel</h3>
<p>Best for producer-consumer communication.</p>
<pre><code class="language-kotlin">Channel&lt;Task&gt;()
</code></pre>
<p>Most Android use cases need Flow more often than Channel.</p>
<hr />
<h2>Race Conditions Still Exist</h2>
<p>Bad:</p>
<pre><code class="language-kotlin">var count = 0

repeat(1000) {
    launch {
        count++
    }
}
</code></pre>
<p>Use:</p>
<pre><code class="language-kotlin">Mutex
AtomicInteger
</code></pre>
<p>for shared mutable state.</p>
<hr />
<h2>Quick Decision Guide</h2>
<table>
<thead>
<tr>
<th>Requirement</th>
<th>Recommended Tool</th>
</tr>
</thead>
<tbody><tr>
<td>Background task</td>
<td>launch</td>
</tr>
<tr>
<td>Need a result</td>
<td>async</td>
</tr>
<tr>
<td>Thread switch</td>
<td>withContext</td>
</tr>
<tr>
<td>UI state</td>
<td>StateFlow</td>
</tr>
<tr>
<td>One-time event</td>
<td>SharedFlow</td>
</tr>
<tr>
<td>Data stream</td>
<td>Flow</td>
</tr>
<tr>
<td>Parallel execution</td>
<td>async + await</td>
</tr>
<tr>
<td>Failure isolation</td>
<td>SupervisorJob</td>
</tr>
<tr>
<td>Android lifecycle work</td>
<td>viewModelScope</td>
</tr>
</tbody></table>
<hr />
<h2>Final Thoughts</h2>
<p>Coroutines are not just about writing asynchronous code.</p>
<p>They're about writing asynchronous code that remains readable, maintainable, efficient, and safe.</p>
<p>Once you understand:</p>
<ul>
<li>Suspension vs Blocking</li>
<li>Dispatchers</li>
<li>CoroutineContext</li>
<li>Structured Concurrency</li>
<li>Cancellation</li>
<li>Exception Propagation</li>
<li>Flow APIs</li>
<li>StateFlow vs SharedFlow</li>
</ul>
<p>Coroutines stop feeling magical and start feeling predictable.</p>
<p>And predictable systems are what great software is built on.</p>
<p>Happy Coding! 🚀</p>
]]></content:encoded></item><item><title><![CDATA[Kotlin Extension Functions Demystified]]></title><description><![CDATA[Coming soon....]]></description><link>https://masterkotlin.com/kotlin-extension-functions-demystified</link><guid isPermaLink="true">https://masterkotlin.com/kotlin-extension-functions-demystified</guid><category><![CDATA[Kotlin]]></category><dc:creator><![CDATA[Abhishek Kumar]]></dc:creator><pubDate>Tue, 11 Jan 2022 05:51:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/lqcvMiBABHw/upload/v1641879927997/wFgZ253YY.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Coming soon....</p>
]]></content:encoded></item></channel></rss>