<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Abizer</title>
    <description>The latest articles on Forem by Abizer (@abizer_r).</description>
    <link>https://forem.com/abizer_r</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F696731%2F83e273c4-cbfc-40a4-bd09-60a8fa98105b.jpg</url>
      <title>Forem: Abizer</title>
      <link>https://forem.com/abizer_r</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/abizer_r"/>
    <language>en</language>
    <item>
      <title>Compose Beginners 2: The Lego Bricks of Android UI</title>
      <dc:creator>Abizer</dc:creator>
      <pubDate>Mon, 03 Nov 2025 21:25:16 +0000</pubDate>
      <link>https://forem.com/abizer_r/compose-beginners-2-the-lego-bricks-of-android-ui-28in</link>
      <guid>https://forem.com/abizer_r/compose-beginners-2-the-lego-bricks-of-android-ui-28in</guid>
      <description>&lt;p&gt;In Blog 1 you discovered why Jetpack Compose transformed Android UI development, moving from mutation-heavy XML to a state-driven, declarative paradigm. Now in Blog 2, we’ll step into the how: what exactly is a @Composable, how to think of it as building Lego bricks for your UI, and how to start building your own interactive UI piece (no XML involved).&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Revisiting the Paradigm Shift
&lt;/h3&gt;

&lt;p&gt;In the first blog you explored how Compose makes UI a function of state rather than a set of mutable views. &lt;br&gt;
Let’s carry that mindset forward:&lt;/p&gt;

&lt;p&gt;Instead of “how do I update the view”, we ask “what should the UI look like given this state?”&lt;/p&gt;

&lt;p&gt;Instead of XML inflation and findViewById(), we get declarative functions.&lt;/p&gt;

&lt;p&gt;Instead of manually tracking UI changes, Compose’s runtime handles recomposition for us.&lt;/p&gt;

&lt;p&gt;In short: we’ve already embraced the why. Now we’ll embrace the what and how of the building blocks.&lt;/p&gt;


&lt;h3&gt;
  
  
  2. Composables = The Lego Bricks
&lt;/h3&gt;

&lt;p&gt;Imagine you’re building a model with Lego bricks. Each brick is simple; you just snap them together. Similarly, a @Composable function is a building-block for your UI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Composable&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;Greeting&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty basic but imagine combining many such composables (bricks) to build your screen. That’s the Compose way.&lt;/p&gt;

&lt;p&gt;Why this analogy helps&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reusable&lt;/strong&gt;: Just like bricks can be used in different models, composables can be reused.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Composable&lt;/strong&gt;: You stack them or nest them (Column, Row, Box) to build screens.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;State-driven&lt;/strong&gt;: When the underlying state changes, only the bricks depending on it are “re-snapped” (recomposed), not everything collapses.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3. What Makes a Function “Composable”
&lt;/h3&gt;

&lt;p&gt;Let’s define it clearly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A function annotated with @Composable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Takes UI inputs (parameters) and draws UI.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Doesn’t return a view — instead it describes part of the UI tree.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can call other composables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Works hand-in-hand with Compose runtime for efficient recomposition.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Composable&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;MyButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onClick&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tap Me"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is your brick: self-contained, parameterised, reusable.&lt;/p&gt;




&lt;p&gt;✅ Fact-Check Note&lt;/p&gt;

&lt;p&gt;As of Compose BOM 2025.09.00 (and Kotlin 2.0+), the Compose compiler transforms composables and the runtime handles composition and recomposition.&lt;br&gt;
Always refer to the official docs.&lt;/p&gt;


&lt;h3&gt;
  
  
  4. Build Your First Interactive Brick (A Counter)
&lt;/h3&gt;

&lt;p&gt;Let’s put all this into action. You don’t need a demo video; you’ll implement and preview with Android Studio’s Preview.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Composable&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;CounterDemo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;count&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;remember&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;mutableStateOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillMaxSize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;horizontalAlignment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Alignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CenterHorizontally&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;verticalArrangement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrangement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Center&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Count: $count"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;style&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MaterialTheme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;typography&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headlineMedium&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nc"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onClick&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;++&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add One"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s what you’ll notice:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;count is state.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When the button is clicked, state changes → Compose recomposes the part of UI displaying the count.&lt;/p&gt;

&lt;p&gt;You didn’t deal with findViewById, Adapter.notifyDataSetChanged(), or manual UI updates.&lt;/p&gt;

&lt;p&gt;A small twist to add delight&lt;/p&gt;

&lt;p&gt;You may swap the static text with a changing emoji:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;emoji&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🌱"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🌿"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🌳"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"🌲"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${emoji[count % emoji.size]}  Count: $count"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See how the UI reflects the state instantly? You’re building with bricks, not manipulating glue.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Why This Building Block Matters
&lt;/h3&gt;

&lt;p&gt;Connecting back to Blog 1: you already understand that Compose changed how we think about UI. Now with composables you see how we build UI under that new thinking.&lt;/p&gt;

&lt;p&gt;Predictability: UI = f(state). Your bricks visualize exactly that.&lt;/p&gt;

&lt;p&gt;Reusability &amp;amp; Modularity: Each composable is a brick you can reuse across screens, which is much easier than large XML layouts with tangled dependencies.&lt;/p&gt;

&lt;p&gt;Performance: Since only affected bricks recompute, you get efficient UI updates without manual optimisation.&lt;/p&gt;




&lt;p&gt;🧠 Reader Takeaway&lt;/p&gt;

&lt;p&gt;You now know what composables are, why they matter, and how to start building UI with them. In the first post you grasped why Compose changed Android. In this post, you’ve begun to grasp how, turning that paradigm into your first bricks.&lt;/p&gt;

</description>
      <category>android</category>
      <category>androiddev</category>
      <category>kotlin</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Compose Beginner 1: Why Jetpack Compose Changed Android Forever</title>
      <dc:creator>Abizer</dc:creator>
      <pubDate>Mon, 27 Oct 2025 10:26:37 +0000</pubDate>
      <link>https://forem.com/abizer_r/compose-beginner-1-why-jetpack-compose-changed-android-forever-3jag</link>
      <guid>https://forem.com/abizer_r/compose-beginner-1-why-jetpack-compose-changed-android-forever-3jag</guid>
      <description>&lt;p&gt;&lt;em&gt;From XML mutations to declarative magic. How Jetpack Compose reshaped how we think about Android UI.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Intro
&lt;/h3&gt;

&lt;p&gt;Most of us build with Jetpack Compose today, but few of us pause to ask &lt;em&gt;why&lt;/em&gt; it changed everything.&lt;br&gt;&lt;br&gt;
In this post, I’ll share how my own Android journey (from &lt;strong&gt;Java + XML&lt;/strong&gt; projects to modern &lt;strong&gt;Compose&lt;/strong&gt; apps) helped me see what truly makes declarative UI different, and why it quietly reshaped how we design, debug, and think about Android.&lt;/p&gt;


&lt;h2&gt;
  
  
  👨‍💻 My Journey: From XML Mutations to Compose Mindset
&lt;/h2&gt;

&lt;p&gt;When I started Android development back in &lt;strong&gt;October 2021&lt;/strong&gt;, I started with the roots, my world was all XML and Java.&lt;br&gt;
My first apps &lt;a href="https://github.com/Abizer-R/LearnHindi" rel="noopener noreferrer"&gt;&lt;strong&gt;LearnHindi&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://github.com/Abizer-R/ShortNews" rel="noopener noreferrer"&gt;&lt;strong&gt;ShortNews&lt;/strong&gt;&lt;/a&gt; were classic View-based projects: &lt;code&gt;findViewById()&lt;/code&gt;, adapters, and endless &lt;code&gt;setText()&lt;/code&gt; calls.  &lt;/p&gt;

&lt;p&gt;It was exciting, but also fragile.&lt;br&gt;&lt;br&gt;
Every UI update felt like diffusing a bomb. You change one thing, break three others.  &lt;/p&gt;

&lt;p&gt;Then I switched to &lt;strong&gt;Kotlin&lt;/strong&gt;, and eventually &lt;strong&gt;Jetpack Compose&lt;/strong&gt; and suddenly, it felt like I was building &lt;em&gt;with&lt;/em&gt; Android, not fighting it.&lt;/p&gt;

&lt;p&gt;Compose wasn’t just new syntax. It was a new &lt;em&gt;way of thinking.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  💡 Compose Didn’t Just Replace XML, it Replaced &lt;em&gt;How We Think About UI&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Compose made our UIs faster to build, but its real gift was &lt;strong&gt;predictability&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
For the first time, the UI became a pure reflection of state, not a pile of mutable views.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“UI is a function of state.”&lt;br&gt;&lt;br&gt;
That’s the line that changed everything.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No more juggling references or wondering if the screen updated correctly.&lt;br&gt;&lt;br&gt;
Now the question was simple: &lt;em&gt;What should this screen look like for the current state?&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  🧠 Declarative vs Imperative: The Core Idea You Already Use (But Might Not Have Named)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Imperative (Old View System)&lt;/th&gt;
&lt;th&gt;Declarative (Compose)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;UI model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mutable tree of Views&lt;/td&gt;
&lt;td&gt;Pure function returning UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;State flow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Push data manually&lt;/td&gt;
&lt;td&gt;UI reacts automatically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ownership&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You own updates&lt;/td&gt;
&lt;td&gt;Compose owns invalidations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mental model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;“When should I update?”&lt;/td&gt;
&lt;td&gt;“What should UI look like now?”&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You already write this daily:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Composable&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;ProfileCard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don’t “set” anything, you describe it.&lt;br&gt;
The function’s output is your UI; Compose handles when and how it changes.&lt;/p&gt;



&lt;p&gt;⚙️ Why Declarative UIs Scale Better&lt;/p&gt;

&lt;p&gt;In XML days:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;textView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Online"&lt;/span&gt;
&lt;span class="n"&gt;progressBar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;visibility&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GONE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You were mutating an object graph while keeping mental tabs on every widget.&lt;/p&gt;

&lt;p&gt;In Compose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Online"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nc"&gt;CircularProgressIndicator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You simply describe what the UI should be, and Compose ensures the screen stays true to state.&lt;br&gt;
That’s why scaling from simple screens to complex, multi-source UIs is finally sane.&lt;/p&gt;




&lt;p&gt;🔬 Under the Hood (2025 Edition)&lt;/p&gt;

&lt;p&gt;By 2025, Compose’s runtime has matured into a highly optimized diff engine.&lt;br&gt;
The compiler tracks which values change and triggers recomposition only where needed.&lt;/p&gt;

&lt;p&gt;You can see it in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;@Stable / @Immutable annotations guiding recomposition&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The new Modifier.Node system improving performance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recomposition tracing built into Layout Inspector (AGP 8.12+)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No hacks, no boilerplate, just a solid, state-driven UI pipeline.&lt;/p&gt;




&lt;p&gt;🧩 The Real Lesson for Compose Developers&lt;/p&gt;

&lt;p&gt;If you’re already using Compose, your next level isn’t learning more APIs, it’s learning to think declaratively across your architecture.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Let state drive everything and no manual “UI updates.”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keep composables pure: inputs in, visuals out.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hoist state properly so logic and UI stay predictable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you adopt that mindset you'll see that testing, previews, and animations stop being chores, they just work.&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>mobile</category>
      <category>androiddev</category>
    </item>
    <item>
      <title>Bad Nesting in Kotlin Coroutines: The Bug That's not a Bug (Until it is)</title>
      <dc:creator>Abizer</dc:creator>
      <pubDate>Wed, 30 Jul 2025 08:16:51 +0000</pubDate>
      <link>https://forem.com/abizer_r/bad-nesting-in-kotlin-coroutines-the-bug-thats-not-a-bug-until-it-is-2jm3</link>
      <guid>https://forem.com/abizer_r/bad-nesting-in-kotlin-coroutines-the-bug-thats-not-a-bug-until-it-is-2jm3</guid>
      <description>&lt;p&gt;⚠️ &lt;strong&gt;IMPORTANT UPDATE&lt;/strong&gt;: &lt;br&gt;
This article describes behavior from Kotlin coroutines versions prior to 0.27.0 (September 2018). &lt;br&gt;
As pointed out by readers, &lt;code&gt;withContext&lt;/code&gt; was changed in version 0.27.0 to "await for all launched tasks," &lt;br&gt;
effectively fixing the "bad nesting" issue described here. &lt;/p&gt;

&lt;p&gt;For historical context and understanding older codebases, the information below remains accurate &lt;br&gt;
for pre-0.27.0 versions. For modern development, this anti-pattern is no longer problematic &lt;/p&gt;
&lt;h2&gt;
  
  
  thanks to the structured concurrency improvements.
&lt;/h2&gt;
&lt;h2&gt;
  
  
  What is “Bad Nesting”?
&lt;/h2&gt;

&lt;p&gt;We all love Kotlin coroutines because they’re clean, powerful, and great for writing async code that &lt;em&gt;almost&lt;/em&gt; feels synchronous. But sometimes, coroutines betray us in the most subtle ways.&lt;/p&gt;

&lt;p&gt;One such betrayal: &lt;strong&gt;bad nesting&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It happens when you put a coroutine builder like &lt;code&gt;launch&lt;/code&gt; or &lt;code&gt;async&lt;/code&gt; &lt;em&gt;inside&lt;/em&gt; a &lt;code&gt;withContext&lt;/code&gt; block, expecting it to behave like structured concurrency.&lt;br&gt;&lt;br&gt;
Spoiler alert: it doesn’t.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Problem in a Nutshell
&lt;/h2&gt;

&lt;p&gt;Bad nesting breaks structured concurrency and leads to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Orphaned coroutines&lt;/strong&gt; (they outlive the parent)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logs that lie to you&lt;/strong&gt; (“done” isn’t really done)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency bugs&lt;/strong&gt; that make you question your sanity&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Let’s See It in Action
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import kotlinx.coroutines.*

fun main() = runBlocking {
    println("Before withContext")

    withContext(Dispatchers.IO) {
        launch {
            delay(1000)
            println("Inside launch")
        }
        println("withContext block done")
    }

    println("After withContext")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before withContext  
withContext block done  
After withContext  
Inside launch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait... the &lt;code&gt;launch&lt;/code&gt; runs &lt;em&gt;after&lt;/em&gt; the outer scope thinks everything’s done?&lt;br&gt;
Yes. And here’s why.&lt;/p&gt;


&lt;h2&gt;
  
  
  What's Really Happening?
&lt;/h2&gt;

&lt;p&gt;Let’s break it down:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;runBlocking&lt;/code&gt; starts your main coroutine.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;withContext(IO)&lt;/code&gt; suspends and shifts work to an IO thread.&lt;/li&gt;
&lt;li&gt;Inside that block, you call &lt;code&gt;launch&lt;/code&gt;. This creates a &lt;strong&gt;new coroutine&lt;/strong&gt;, not tracked by &lt;code&gt;withContext&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;withContext&lt;/code&gt; runs the block, hits the last line (&lt;code&gt;println&lt;/code&gt;) and… finishes.&lt;/li&gt;
&lt;li&gt;The program resumes, &lt;strong&gt;even though &lt;code&gt;launch&lt;/code&gt; is still running&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That &lt;code&gt;launch&lt;/code&gt; is now a &lt;strong&gt;zombie coroutine&lt;/strong&gt;, alive and unsupervised.&lt;br&gt;
Remember: Job of &lt;code&gt;withContext()&lt;/code&gt; is to switch dispatchers (threads) without starting a new coroutine. It doesn't track and wait for any coroutines launched inside it before returning.&lt;/p&gt;


&lt;h2&gt;
  
  
  Let Me Paint You a Picture
&lt;/h2&gt;

&lt;p&gt;Imagine you're a team lead. You tell your assistant:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Go to the warehouse and make sure all boxes are stacked.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The assistant walks in, but instead of doing the stacking, he calls someone else and immediately walks out.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Boxes are stacked, boss!”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Meanwhile, the boxes are still lying around, unstacked.&lt;/p&gt;

&lt;p&gt;That’s exactly what happens when you &lt;code&gt;launch&lt;/code&gt; inside &lt;code&gt;withContext&lt;/code&gt;. The block returns, but the actual task isn’t finished.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why Is This Dangerous?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You might start reading shared data &lt;strong&gt;before&lt;/strong&gt; it’s been updated.&lt;/li&gt;
&lt;li&gt;Cleanup might run &lt;strong&gt;before&lt;/strong&gt; a job is complete.&lt;/li&gt;
&lt;li&gt;Background tasks might leak or throw unexpected errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You think everything is done, but some coroutine is silently working in the background. &lt;strong&gt;That's a recipe for race conditions and flaky bugs&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  How to Fix It
&lt;/h2&gt;

&lt;p&gt;You’ve got two clean options depending on what you want:&lt;/p&gt;


&lt;h3&gt;
  
  
  1. &lt;strong&gt;Just do the work inside &lt;code&gt;withContext&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;withContext(Dispatchers.IO) {
    delay(1000)
    println("Done properly")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;No &lt;code&gt;launch&lt;/code&gt;. Just let &lt;code&gt;withContext&lt;/code&gt; suspend until it’s done.&lt;/p&gt;


&lt;h3&gt;
  
  
  2. &lt;strong&gt;Use &lt;code&gt;coroutineScope&lt;/code&gt; inside &lt;code&gt;withContext&lt;/code&gt; if you need multiple launches&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;withContext(Dispatchers.IO) {
    coroutineScope {
        launch {
            delay(1000)
            println("Task 1 done")
        }
        launch {
            delay(500)
            println("Task 2 done")
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task 2 done  
Task 1 done  
After all tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;code&gt;coroutineScope&lt;/code&gt; ensures that &lt;code&gt;withContext&lt;/code&gt; won’t finish until &lt;em&gt;all its child coroutines&lt;/em&gt; have completed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bad Nesting in Real Life
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Orphaned Coroutine Example&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;withContext(Dispatchers.IO) {
    launch {
        delay(1000)
        println("Still running after withContext ends 😵")
    }
    println("withContext done")
}
println("runBlocking done")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;withContext done  
runBlocking done  
Still running after withContext ends 😵
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. &lt;strong&gt;Race Condition Example&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;withContext(Dispatchers.IO) {
    launch {
        delay(1000)
        println("Updating shared resources")
    }
    println("Assuming updates are done 🤡")
}
println("Reading shared resources 😬")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧾 Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Assuming updates are done 🤡  
Reading shared resources 😬  
Updating shared resources
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yikes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Bad nesting is sneaky because it looks innocent, but it quietly breaks everything structured concurrency stands for.&lt;/p&gt;

&lt;p&gt;Next time you're inside a &lt;code&gt;withContext&lt;/code&gt;, ask yourself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Am I &lt;em&gt;doing&lt;/em&gt; the work, or am I &lt;em&gt;delegating&lt;/em&gt; it?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If it's the latter, make sure you're supervising the workers properly using coroutineScope. 😉&lt;/p&gt;




&lt;h3&gt;
  
  
  ✍️ About the Author
&lt;/h3&gt;

&lt;p&gt;Hey! I’m Abizer, an Android developer who’s into finding weird bugs that make for great blog posts.&lt;/p&gt;

&lt;p&gt;If this helped you out, follow me here or connect on &lt;a href="https://github.com/Abizer-R" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; / &lt;a href="https://www.linkedin.com/in/abizer-rampurawala/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Have you been bitten by bad coroutine nesting? Share your bug story in the comments!&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
      <category>coroutines</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
