{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "@okmanideep",
  "language": "en",
  "home_page_url": "https://okmanideep.me/",
  "feed_url": "https://okmanideep.me/feed.json",
  "description": "Android · Web · Design",
  "author": {
    "name": "Manideep Polireddi",
    "url": "https://twitter.com/okmanideep"
  },
  "items": [
    {
      "id": "https://okmanideep.me/its-a-c-at-best/",
      "url": "https://okmanideep.me/its-a-c-at-best/",
      "title": "It&#39;s a C+ at best",
      "content_html": "<p>It's a C+ at best. That's what Nilay Patel, editor-in-chief of The Verge, had to say about ChatGPT's writing ability about a year ago. I was surprised at first because I thought LLMs were great at writing—but then I realized he had spent over a decade writing and editing high-quality articles. It was just a passing comment in a larger conversation about the promise of the AI industry, but often, I find myself coming back to it. It’s helped me maintain a balanced mindset about AI tools and how I adopt them at work.</p>\n<blockquote>\n<p>Happiness is reality minus expectations<br />\n— Tom Magliozzi</p>\n</blockquote>\n<p>Software tools, historically, have been extremely good at being reliable. Their deterministic nature has helped set appropriate expectations for the people using them. LLMs are not that. They are probabilistic at their core. So we need to find a way to tone down our expectations when using AI tools. <strong>Viewing AI as a fast and always available intern whose output is C+ at best</strong> helps me set reasonable expectations. Expectations that keep me cautious while not becoming frustrated when they get things wrong.</p>\n<blockquote>\n<p>If you never try, you'll never know what you're capable of.<br />\n— John Barrow</p>\n</blockquote>\n<p>I could be an expert in my domain. But there is a lot of day-to-day work where I could use some help. Modern software development (or many modern jobs, for that matter) requires us to understand and contribute in many adjacent domains. Now, I have an intern who, while not perfect, is more confident and potentially knowledgeable than me in those domains. That helps me cross some bridges I am hesitant to approach. It's still <em>C+ at best</em>, but many times, that's good enough. In a completely new area, C+ is a great start.</p>\n<blockquote>\n<p>If you want to build a great company, you have to surround yourself with A players<br />\n— Steve Jobs</p>\n</blockquote>\n<p>I am expected to do A+ work—especially in my core domain. I can't fully delegate it to a C+ intern and call it a day. If the intern ends up saving my time, I ought to use the saved time to make my work much better. Sometimes, the intern doesn't save any time—and that's OK. It's nothing new. Interns often take more time from you than they save.</p>\n<blockquote>\n<p>'What's not going to change in the next 10 years?' is the more important question<br />\n— Jeff Bezos</p>\n</blockquote>\n<p>Nilay might grade the new models higher, and indeed, LLMs have improved significantly. But, the exact grade matters less than their true nature: usually <em>good enough</em> but rarely <em>exceptional</em>. That's still the case and likely going to be the case for as long as they are trained using the whole of human mediocrity. A little adjustment in mindset can get the best out of us <em>with</em> AI.</p>\n",
      "date_published": "2025-04-21T14:22:00Z"
    }
    ,
    {
      "id": "https://okmanideep.me/nushell-after-8-months/",
      "url": "https://okmanideep.me/nushell-after-8-months/",
      "title": "Nushell, after 8 months",
      "content_html": "<blockquote>\n<p>... Plain text is definitely simpler than tables. So maybe we are just moving complexity here. Or this is a very good abstraction and a lot of things improve. Time will tell.</p>\n</blockquote>\n<p><a href=\"https://okmanideep.me/i-am-very-excited-about-using-nushell-everyday/\">Me, 8 months ago</a></p>\n<p>And the last 8 months have told me - Tables are a very good abstraction for CLI. No doubt. Possibly because they retain the fundamental nature of <a href=\"https://youtu.be/-6BsiVyC1kM?si=w1U3f4OzdOAT6C55\">Values</a>. In fact, tables are already present in unix shell, hiding in plain text. <code>ps</code>, <code>ll</code>, <code>kubectl</code> and many more programs have a tabular output. And to do anything with them, it's a lot more easier in <code>nushell</code> than in <code>bash</code> or similar shells.</p>\n<h2>Surprisingly seamless 🧈</h2>\n<p>I had my concerns initially - &quot;Won't I face a lot of issues with all the unix programs, that just expect plain text and output plain text?&quot;. But it's barely been a problem. <code>nushell</code>'s inbuilt commands and operators just take care of converting plain text to structured data and extract the necessary values to pipe them back into other programs.</p>\n<p>Let's take an example. Get the first pod's name with the status <code>Running</code> in a kubernetes cluster and enter it's shell?</p>\n<pre class=\"language-sh\"><code class=\"language-sh\">$ kubectl <span class=\"token parameter variable\">-n</span> namespace get pods</code></pre>\n<p>gets you a table like this</p>\n<pre><code>NAME                                                 READY   STATUS      RESTARTS      AGE\nnamespace-86c7df9555-4n9cc                             1/1     Running     0             2d2h\nnamespace-86c7df9555-65nks                             1/1     Running     0             2d2h\nnamespace-86c7df9555-cdzll                             1/1     Running     1 (35h ago)   2d1h\nnamespace-86c7df9555-dlpnx                             1/1     Running     0             35h\nnamespace-86c7df9555-fnrgd                             1/1     Running     0             2d2h\nnamespace-86c7df9555-lnx2v                             1/1     Running     0             2d1h\nnamespace-86c7df9555-nmwrx                             1/1     Running     0             2d2h\nnamespace-86c7df9555-xv45m                             1/1     Running     0             35h\n</code></pre>\n<p>This is just plain text but pipe it into <code>detect columns</code> and we get an actual <code>nushell</code> table</p>\n<pre class=\"language-sh\"><code class=\"language-sh\">$ kubectl <span class=\"token parameter variable\">-n</span> namespace get pods <span class=\"token operator\">|</span> detect columns</code></pre>\n<img src=\"https://imgur.com/k5im8XR.png\" style=\"max-width: 680px;\" />\n<p>Now we can filter the rows with <code>where</code> and get the first row with <code>first</code></p>\n<pre class=\"language-sh\"><code class=\"language-sh\">$ kubectl <span class=\"token parameter variable\">-n</span> namespace get pods <span class=\"token operator\">|</span> detect columns <span class=\"token operator\">|</span> where <span class=\"token punctuation\">{</span> <span class=\"token variable\">$it</span>.STATUS <span class=\"token operator\">==</span> <span class=\"token string\">\"Running\"</span> <span class=\"token punctuation\">}</span> <span class=\"token operator\">|</span> first <span class=\"token operator\">|</span> get NAME</code></pre>\n<p>We can store this in a variable and access the shell with <code>kubectl exec</code></p>\n<pre class=\"language-sh\"><code class=\"language-sh\">$ <span class=\"token builtin class-name\">let</span> pod_id <span class=\"token operator\">=</span> kubectl <span class=\"token parameter variable\">-n</span> namespace get pods <span class=\"token operator\">|</span> detect columns <span class=\"token operator\">|</span> where <span class=\"token punctuation\">{</span> <span class=\"token variable\">$it</span>.STATUS <span class=\"token operator\">==</span> <span class=\"token string\">\"Running\"</span> <span class=\"token punctuation\">}</span> <span class=\"token operator\">|</span> first <span class=\"token operator\">|</span> get NAME<br />$ kubectl <span class=\"token parameter variable\">-n</span> namespace <span class=\"token builtin class-name\">exec</span> <span class=\"token parameter variable\">-it</span> <span class=\"token variable\">$pod_id</span> -- /bin/bash</code></pre>\n<p>Or just put it in <code>()</code> brackets and use it directly</p>\n<pre class=\"language-sh\"><code class=\"language-sh\">$ kubectl <span class=\"token parameter variable\">-n</span> namespace <span class=\"token builtin class-name\">exec</span> <span class=\"token parameter variable\">-it</span> <span class=\"token punctuation\">(</span>kubectl <span class=\"token parameter variable\">-n</span> namespace get pods <span class=\"token operator\">|</span> detect columns <span class=\"token operator\">|</span> where <span class=\"token punctuation\">{</span> <span class=\"token variable\">$it</span>.STATUS <span class=\"token operator\">==</span> <span class=\"token string\">\"Running\"</span> <span class=\"token punctuation\">}</span> <span class=\"token operator\">|</span> first <span class=\"token operator\">|</span> get NAME<span class=\"token punctuation\">)</span> -- /bin/bash</code></pre>\n<p>Working within <code>nushell</code> has been a lot like working with the programming languages that I am used to. It feels like I am in a REPL of one of those languages. Familiar and comfortable.</p>\n<h2>Perfect for data wrangling ⚙️</h2>\n<p>Lately I have been working with some csv files and what a delight it has been to work with them in <code>nushell</code>.</p>\n<p>Colleague pings me saying &quot;Here are the leads we want to add to the database - leads.csv&quot;.</p>\n<p>I take a look at the file and there are some invalid user_ids in the file.</p>\n<pre class=\"language-sh\"><code class=\"language-sh\"><span class=\"token function\">open</span> leads.csv <span class=\"token operator\">|</span> where <span class=\"token punctuation\">{</span> <span class=\"token punctuation\">(</span><span class=\"token variable\">$it</span>.user_id <span class=\"token operator\">|</span> describe<span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token string\">'int'</span> <span class=\"token punctuation\">}</span> <span class=\"token operator\">|</span> count</code></pre>\n<p>I inform him - &quot;Hey, we have 32 invalid user_ids in the leads.csv file. I will ignore them for now.&quot; and move on.</p>\n<pre class=\"language-sh\"><code class=\"language-sh\"><span class=\"token function\">open</span> leads.csv <span class=\"token operator\">|</span> where <span class=\"token punctuation\">{</span> <span class=\"token punctuation\">(</span><span class=\"token variable\">$it</span>.user_id <span class=\"token operator\">|</span> describe<span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token string\">'int'</span> <span class=\"token punctuation\">}</span> <span class=\"token operator\">|</span> get user_id <span class=\"token operator\">|</span> str <span class=\"token function\">join</span> <span class=\"token string\">','</span> <span class=\"token operator\">|</span> pbcopy</code></pre>\n<p>(Copies the user_ids to the clipboard)</p>\n<p>I can probably do the same with <code>awk</code> and <code>sed</code> in <code>bash</code>. But this is a lot more simpler for me. Possibly because I work with object oriented languages a lot. And commands like <code>where</code>, <code>first</code>, <code>take</code>, <code>skip</code> are very familiar to me because all the languages have adopted these functional paradigms for operating with collections / streams.</p>\n<p>By the way, if I want to convert that CSV to JSON?</p>\n<pre class=\"language-sh\"><code class=\"language-sh\"><span class=\"token function\">open</span> leads.csv <span class=\"token operator\">|</span> to json <span class=\"token operator\">|</span> pbcopy</code></pre>\n<p>Ready to just paste it into a node REPL.</p>\n<p>This works with CSV, JSON, YAML, TOML, SQLite and <a href=\"http://www.nushell.sh/book/loading_data.html#opening-files\">many more formats</a>. This came in handy to check which exact version of package is being used in a <code>package-lock.json</code> file a number of times.</p>\n<pre class=\"language-sh\"><code class=\"language-sh\"><span class=\"token function\">open</span> package-lock.json <span class=\"token operator\">|</span> get dependencies.ws.version</code></pre>\n<h2>How big is this Advent of Code input?</h2>\n<div style=\"width: 100%; height: 489px; background: var(--raised-bg-color)\">\n\t<script src=\"https://asciinema.org/a/717382.js\" id=\"asciicast-717382\" async=\"true\" data-autoplay=\"\"></script>\n</div>\n<p>number of lines</p>\n<pre class=\"language-sh\"><code class=\"language-sh\"><span class=\"token function\">cat</span> inputs/day12.txt <span class=\"token operator\">|</span> lines <span class=\"token operator\">|</span> length</code></pre>\n<p>number of characters per line</p>\n<pre class=\"language-sh\"><code class=\"language-sh\"><span class=\"token function\">cat</span> inputs/day12.text <span class=\"token operator\">|</span> lines <span class=\"token operator\">|</span> first <span class=\"token operator\">|</span> <span class=\"token function\">split</span> chars <span class=\"token operator\">|</span> length</code></pre>\n<h2>It can't all be that good, can it?</h2>\n<p>While I was about to adopt a new shell that's not 1.0 yet, I was expecting to deal with some rough edges.</p>\n<blockquote>\n<p>It feels like a pre-honeymoon phase with nu. So there is a lot of adulation right now. It's likely that there are a lot of sour learnings to follow</p>\n</blockquote>\n<p><a href=\"https://okmanideep.me/i-am-very-excited-about-using-nushell-everyday/\">Me, 8 months ago</a></p>\n<p>To be honest, I didn't have to deal with many issues. But there was one which took a bit of time to figure out.</p>\n<p><a href=\"https://github.com/Schniz/fnm\">fnm</a> - fast node version manager, only offer setup instructions for <code>bash</code>, <code>zsh</code>, <code>fish</code> and <code>powershell</code> to add necessary changes to the shell profile for the right $PATH. For <code>nushell</code>, we have to use something like this</p>\n<pre class=\"language-sh\"><code class=\"language-sh\"><span class=\"token comment\"># fnm - node version manager</span><br /><span class=\"token comment\"># https://dev.to/vaibhavdn/using-fnm-with-nushell-3kh1</span><br />load-env <span class=\"token punctuation\">(</span>/opt/homebrew/bin/fnm <span class=\"token function\">env</span> <span class=\"token parameter variable\">--shell</span> <span class=\"token function\">bash</span> <span class=\"token operator\">|</span> lines <span class=\"token operator\">|</span> str replace <span class=\"token string\">'export '</span> <span class=\"token string\">''</span> <span class=\"token operator\">|</span> str replace <span class=\"token parameter variable\">-a</span> <span class=\"token string\">'\"'</span> <span class=\"token string\">''</span> <span class=\"token operator\">|</span> <span class=\"token function\">split</span> <span class=\"token function\">column</span> <span class=\"token operator\">=</span> <span class=\"token operator\">|</span> <span class=\"token function\">rename</span> name value <span class=\"token operator\">|</span> where name <span class=\"token operator\">!=</span> <span class=\"token string\">\"FNM_ARCH\"</span> and name <span class=\"token operator\">!=</span> <span class=\"token string\">\"PATH\"</span> <span class=\"token operator\">|</span> reduce <span class=\"token parameter variable\">-f</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span> <span class=\"token punctuation\">{</span><span class=\"token operator\">|</span>it, acc<span class=\"token operator\">|</span> <span class=\"token variable\">$acc</span> <span class=\"token operator\">|</span> upsert <span class=\"token variable\">$it</span>.name <span class=\"token variable\">$it</span>.value <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><br /><br /><span class=\"token variable\">$env</span><span class=\"token builtin class-name\">.</span><span class=\"token environment constant\">PATH</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token variable\">$env</span><span class=\"token builtin class-name\">.</span><span class=\"token environment constant\">PATH</span> <span class=\"token operator\">|</span> prepend $<span class=\"token string\">\"(<span class=\"token variable\">$env</span>.FNM_MULTISHELL_PATH)/bin\"</span><span class=\"token punctuation\">)</span></code></pre>\n<p>Essentially fake the shell, get the necessary changes and apply them to the <code>nushell</code> environment.</p>\n<p>Some extra work to setup programs that output configuration for bash / zsh etc. And a few copy pasta for setting up some completions.</p>\n<p>That's about it. After I have setup <code>nushell</code> in my system and added it to my <a href=\"https://github.com/okmanideep/dotfiles\">dotfiles</a>, it's been a smooth ride across both Windows and MacOS. I have been using <code>nushell</code> as my primary shell for the last 8 months and I don't see myself going back to <code>bash</code> or <code>zsh</code> or <code>powershell</code>.</p>\n",
      "date_published": "2024-04-29T11:15:00Z"
    }
    ,
    {
      "id": "https://okmanideep.me/i-am-very-excited-about-using-nushell-everyday/",
      "url": "https://okmanideep.me/i-am-very-excited-about-using-nushell-everyday/",
      "title": "I am very excited about using nushell everyday",
      "content_html": "<p>From the moment I saw the <a href=\"https://youtu.be/bMpYyqWCzZk?si=VLXcaCFLT2p_fHXf\">intro video</a> I found it very appealing. It takes the best of <code>bash</code>(in unix) and <code>powershell</code>. I will assume you could totally relate to the <code>bash</code> part of that sentence.</p>\n<h2>What's best in <code>powershell</code>?</h2>\n<p>I like the structural data flow in <code>powershell</code>. Since <code>powershell</code> commands aren't as well named for casual and quick scripting, it doesn't look good. But my OOP brain that could not master regex or <code>awk</code> in a decade was attracted to the named, associative data structures moving through the command pipeline.</p>\n<p>I remember the first time I was trying to find the last modified file in a directory in a terminal running <code>bash</code>. I knew <code>ls</code> and I knew <code>sort</code>. I was totally in awe of the unix philosophy - individual programs doing only one thing and doing it well, composing different programs to solve complicated problems. So I tried</p>\n<pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">ls</span> <span class=\"token operator\">|</span> <span class=\"token function\">sort</span></code></pre>\n<img src=\"https://i.imgur.com/i0FEqKZ.jpg\" alt=\"ls and sort in bash\" style=\"max-width:480px;\" />\n<p>🤔: <em>Oh! <code>ls</code> only outputs names. So I should use <code>ll</code> in this case</em></p>\n<pre class=\"language-bash\"><code class=\"language-bash\">$ ll <span class=\"token operator\">|</span> <span class=\"token function\">sort</span></code></pre>\n<img src=\"https://i.imgur.com/ew8uvmA.jpg\" alrt=\"ll and sort in bash\" style=\"max-width: 600px;\" />\n<p>🤔: <em>But how do I tell the <code>sort</code> command which property to use for sorting? Does it use size? Does it use the file name?</em></p>\n<p>I was obviously missing something. I found the answer with a quick Google. There is a <code>-t</code> flag on <code>ls</code></p>\n<p>So <code>ls</code> also does sorting. That's... not... simple... right?</p>\n<p>You get the point. So let's see how it works in <code>powershell</code></p>\n<pre class=\"language-sh\"><code class=\"language-sh\">$ Get-ChildItem <span class=\"token operator\">|</span> Sort-Object <span class=\"token parameter variable\">-Property</span> LastWriteTime <span class=\"token parameter variable\">-Descending</span></code></pre>\n<p>I told you it doesn't look good. Ok, you can make it slightly better with the built in aliases and lowercase letters, but the most good looking you can get is</p>\n<pre class=\"language-sh\"><code class=\"language-sh\">$ <span class=\"token function\">ls</span> <span class=\"token operator\">|</span> sort-object <span class=\"token parameter variable\">-property</span> lastwritetime <span class=\"token parameter variable\">-descending</span></code></pre>\n<img src=\"https://i.imgur.com/xvMFXrr.jpg\" alt=\"last modified files in powershell\" style=\"max-width: 600px\" />\n<h5>What is happening here?</h5>\n<p>Unlike plain strings in <code>bash</code>, in <code>powershell</code> we deal with structured data. <code>ls</code> outputs a table with columns - <code>Mode</code>, <code>LastWriteTime</code>, <code>Length</code> and <code>Name</code>. Which I can use further in the command pipeline to tell the <code>sort-object</code> command to sort the table using <code>lastwritetime</code> property</p>\n<p>It doesn't look like the most convenient to type but I can understand how this works and use it in more places for solving more problems than the <code>-t</code> flag on <code>ls</code>.</p>\n<h2>So... Nushell</h2>\n<p>This is how you do the same thing in <code>nu</code></p>\n<pre class=\"language-sh\"><code class=\"language-sh\">$ <span class=\"token function\">ls</span> <span class=\"token operator\">|</span> sort-by <span class=\"token parameter variable\">-r</span> modified</code></pre>\n<p>Just like <code>powershell</code>, <code>ls</code> outputs a table</p>\n<img src=\"https://i.imgur.com/tZEXjpl.jpg\" alt=\"ls in nushell\" style=\"max-width: 480px\" />\n<p>But the names are much better. They bring the comfort and fun that was missing in using <code>powershell</code>. As I said, best of both worlds. <a href=\"https://www.nushell.sh/\">Nushell's homepage</a> has an even better example.</p>\n<img src=\"https://www.nushell.sh/frontpage/ls-example.png\" alt=\"ls in nushell\" style=\"max-width: 600px\" />\n<h2>I am also excited about the speed</h2>\n<p><code>powershell</code> was very slow to start. I guess it's mostly because of the plugins I am <code>import</code>ing in my profile but it takes 1500ms+ to initiliaze after a restart, and ~1000ms for every new tab I open in my terminal.</p>\n<img src=\"https://i.imgur.com/oo37EzL.jpg\" alt=\"powershell startup message with 969ms initialization time\" style=\"max-width: 480px\" />\n<p>This is after I have spent some time profiling and optimizing. I removed a few plugins that were good to have but not must haves.</p>\n<p>I have been living with this for <a href=\"https://github.com/okmanideep/dotfiles/commit/baf2df87224fb86ce5af59b058955b4cfd5e1b50\">well over an year</a>. Why you ask? Because I <strong>hate</strong> lock in. I remember watching all the sensible features Microsoft was bringing to Windows that were aimed directly at developers and wanting to give it a try. And then I realized I actually can't, with my current workflow. It's a long boring journey that we can talk later. But <code>powershell</code> was the only cross platform shell I could find to have a consistent workflow between my PC at home and my office Mac.</p>\n<p>And <code>nu</code> startup in less than <strong>100ms</strong> after I have configured it to my liking with largely same behaviors.</p>\n<img src=\"https://i.imgur.com/40pcOjZ.jpg\" alt=\"nushell startup message with 94ms startup time\" style=\"max-width: 600px\" />\n<p>Besides startup, the speed while usage isn't much different. It's barely noticeable and I won't be surprised if <code>powershell</code> beats <code>nu</code> in a few cases. But being ready to type as soon as I press the short cut for new tab, feels very nice.</p>\n<p>I also have <code>vi</code> mode on the command line. I don't have to Google &quot;move the cursor back word by word in command line&quot; anymore.</p>\n<h2>⚠️</h2>\n<p>I am still a noob in <code>bash</code> and <code>powershell</code>. And I am a mega noob in <code>nushell</code>. It feels like a <em>pre-honeymoon</em> phase with <code>nu</code>. So there is a lot of adulation right now. It's likely that there are a lot of sour learnings to follow. Plain text is definitely simpler than tables. So maybe we are just moving complexity here. Or this is a very good abstraction and a lot of things improve. Time will tell.</p>\n<p>If you are as intrigued by <a href=\"https://www.nushell.sh/\"><code>nushell</code></a> as I am and want to give it a spin, I will warn you about one key thing - The language that is used for configuration and scripting - <code>nu</code> is not locked yet. They intend to evolve it and mercilessly break things until 1.0. You've been warned.</p>\n",
      "date_published": "2023-08-28T13:00:00Z"
    }
    ,
    {
      "id": "https://okmanideep.me/migrating-to-dart-3-and-null-safety/",
      "url": "https://okmanideep.me/migrating-to-dart-3-and-null-safety/",
      "title": "Migrating to Dart 3 and null safety",
      "content_html": "<p>Dart 3 🎯 is here! And it brings very useful features like <code>sealed</code> classes, pattern matching and <a href=\"https://www.youtube.com/watch?v=yRlwOdCK7Ho&amp;t=1766s\">many more</a>.</p>\n<p>It also <strong>ends the support for <code>--no-sound-null-safety</code></strong>.</p>\n<p>Which means to adopt it in any codebase, every single file should be null safe.</p>\n<p>Like us at <a href=\"https://github.com/praja\">Praja</a>, if you have started writing your Flutter app more than a couple of years ago, you would have started slowly migrating your codebase to sound null safety. Some of you would have completed it. If you are one of them <a href=\"https://twitter.com/okmanideep\">I would like to here about your experience</a> and learn what helped and what didn't.</p>\n<p>If you are still going through this transition, I hope this helps you. Here's how we have approached it.</p>\n<h3>Preread 📄</h3>\n<p><a href=\"https://dart.dev/null-safety/migration-guide\">Official Dart Guide for migrating to null safety</a></p>\n<h3>1. Mark all your existing files as not null safe 🏁</h3>\n<p>Skip this step if you have already done it.</p>\n<ul>\n<li>Upgrade dart to 2.12+</li>\n<li>Add <code>// @dart = 2.9</code> to the starting of every dart file in your project and manually convert your <code>main.dart</code></li>\n</ul>\n<p>The following script can help you out here</p>\n<pre class=\"language-ruby\"><code class=\"language-ruby\"><span class=\"token comment\">#!/usr/bin/env ruby</span><br /><br />directory <span class=\"token operator\">=</span> <span class=\"token string-literal\"><span class=\"token string\">\"/lib\"</span></span><br /><br /><span class=\"token comment\"># Navigate to the directory</span><br /><span class=\"token builtin\">Dir</span><span class=\"token punctuation\">.</span>chdir<span class=\"token punctuation\">(</span>directory<span class=\"token punctuation\">)</span><br /><br /><span class=\"token comment\"># Loop through each .dart file in the directory</span><br /><span class=\"token builtin\">Dir</span><span class=\"token punctuation\">.</span>glob<span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"**/*.dart\"</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">each</span> <span class=\"token keyword\">do</span> <span class=\"token operator\">|</span>file<span class=\"token operator\">|</span><br />  <span class=\"token comment\"># Check if the file is a regular file</span><br />  <span class=\"token keyword\">if</span> <span class=\"token builtin\">File</span><span class=\"token punctuation\">.</span>file<span class=\"token operator\">?</span><span class=\"token punctuation\">(</span>file<span class=\"token punctuation\">)</span><br />    <span class=\"token comment\"># Prepend \"// @dart=2.9\" to the file</span><br />    content <span class=\"token operator\">=</span> <span class=\"token builtin\">File</span><span class=\"token punctuation\">.</span>read<span class=\"token punctuation\">(</span>file<span class=\"token punctuation\">)</span><br />    <span class=\"token builtin\">File</span><span class=\"token punctuation\">.</span>open<span class=\"token punctuation\">(</span>file<span class=\"token punctuation\">,</span> <span class=\"token string-literal\"><span class=\"token string\">\"w\"</span></span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">do</span> <span class=\"token operator\">|</span>f<span class=\"token operator\">|</span><br />      f<span class=\"token punctuation\">.</span>write<span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"// @dart=2.9\\n</span><span class=\"token interpolation\"><span class=\"token delimiter punctuation\">#{</span><span class=\"token content\">content</span><span class=\"token delimiter punctuation\">}</span></span><span class=\"token string\">\"</span></span><span class=\"token punctuation\">)</span><br />    <span class=\"token keyword\">end</span><br />    puts <span class=\"token string-literal\"><span class=\"token string\">\"Added // @dart=2.9 to </span><span class=\"token interpolation\"><span class=\"token delimiter punctuation\">#{</span><span class=\"token content\">file</span><span class=\"token delimiter punctuation\">}</span></span><span class=\"token string\">\"</span></span><br />  <span class=\"token keyword\">end</span><br /><span class=\"token keyword\">end</span></code></pre>\n<p>With this you can start using <code>flutter run --no-sound-null-safety</code> and run your app as always</p>\n<h3>2. Add a PR check as a nudge for your team ✅</h3>\n<p>Since this doesn't immediately impact the product, it's not going to be worth it to migrate all the files as a single task / project. We want to do this gradually over a few months. For that, we'd like some regular nudges to everyone in the team to slowly convert files they are touching.</p>\n<p>A PR check like this can help out in a big way</p>\n<pre class=\"language-yaml\"><code class=\"language-yaml\"><span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> Dart Null Safety Validation<br /><span class=\"token key atrule\">on</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>pull_request<span class=\"token punctuation\">]</span><br /><br /><span class=\"token key atrule\">env</span><span class=\"token punctuation\">:</span><br />  <span class=\"token key atrule\">GITHUB_BASE_REF</span><span class=\"token punctuation\">:</span> $<br />  <br /><span class=\"token key atrule\">jobs</span><span class=\"token punctuation\">:</span><br />  <span class=\"token key atrule\">validate</span><span class=\"token punctuation\">:</span><br />    <span class=\"token key atrule\">runs-on</span><span class=\"token punctuation\">:</span> ubuntu<span class=\"token punctuation\">-</span>latest<br />    <span class=\"token key atrule\">steps</span><span class=\"token punctuation\">:</span><br />      <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> Checkout code<br />        <span class=\"token key atrule\">uses</span><span class=\"token punctuation\">:</span> actions/checkout@v3<br />      <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> Validate Dart files<br />        <span class=\"token key atrule\">shell</span><span class=\"token punctuation\">:</span> bash<br />        <span class=\"token key atrule\">run</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">|</span><span class=\"token scalar string\"><br />          # Fetch the base branch for diffing<br />          git fetch origin $GITHUB_BASE_REF:$GITHUB_BASE_REF</span><br /><br />          n_files=$((grep <span class=\"token punctuation\">-</span>r <span class=\"token punctuation\">-</span>H <span class=\"token punctuation\">-</span><span class=\"token punctuation\">-</span>include \\<span class=\"token important\">*.dart</span> \"// @dart = 2.9\" $(git diff <span class=\"token punctuation\">-</span><span class=\"token punctuation\">-</span>name<span class=\"token punctuation\">-</span>only $GITHUB_BASE_REF <span class=\"token punctuation\">-</span><span class=\"token punctuation\">-</span>diff<span class=\"token punctuation\">-</span>filter=AMR) <span class=\"token punctuation\">|</span><span class=\"token punctuation\">|</span> true) <span class=\"token punctuation\">|</span> wc <span class=\"token punctuation\">-</span>l)<br /><br />          if <span class=\"token punctuation\">[</span> $n_files <span class=\"token punctuation\">-</span>ne 0 <span class=\"token punctuation\">]</span>; then<br />            echo \"Dart Files that changed<span class=\"token punctuation\">,</span> but still contain 2.9 dart version<span class=\"token punctuation\">:</span>\"<br />            grep <span class=\"token punctuation\">-</span>r <span class=\"token punctuation\">-</span>H <span class=\"token punctuation\">-</span><span class=\"token punctuation\">-</span>include \\<span class=\"token important\">*.dart</span> \"// @dart = 2.9\" $(git diff <span class=\"token punctuation\">-</span><span class=\"token punctuation\">-</span>name<span class=\"token punctuation\">-</span>only $GITHUB_BASE_REF <span class=\"token punctuation\">-</span><span class=\"token punctuation\">-</span>diff<span class=\"token punctuation\">-</span>filter=AMR)<br />            echo \"\\n\"<br />            echo \"Please convert the above files to project dart version\"<br />            exit 1<br />          fi<br /></code></pre>\n<p>This validates that all <code>.dart</code> files added/modified in a PR are null safe.</p>\n<p>Based on your team, you can choose to make this an optional or a required check. We chose to have it as optional and it worked out for us.</p>\n<p>With just this, over a couple of months, we converted over half the codebase to null safety!</p>\n<h3>3. Highlight low hanging fruits 🍎</h3>\n<p>There are bound to be some files which are not touched at all and are lying there, which stop your from adopting full sound null safety. The PR check is not going to help here.</p>\n<p>A small script that can tell you how many files are left to convert and what are few low hanging fruits helps quite a bit</p>\n<img src=\"https://okmanideep.me/img/null-safe-report-usage.png\" />\n<pre class=\"language-ruby\"><code class=\"language-ruby\"><span class=\"token comment\"># frozen_string_literal: true</span><br /><br /><span class=\"token comment\"># Usage:</span><br /><span class=\"token comment\"># From the root of this project</span><br /><span class=\"token comment\"># $ ruby scripts/null_safe_report.rb ./lib</span><br /><span class=\"token keyword\">require</span> <span class=\"token string-literal\"><span class=\"token string\">'find'</span></span><br /><br /><span class=\"token comment\"># This class is used to sort the files by line count</span><br /><span class=\"token keyword\">class</span> <span class=\"token class-name\">FileToConvert</span><br />  <span class=\"token keyword\">def</span> <span class=\"token method-definition\"><span class=\"token function\">initialize</span></span><span class=\"token punctuation\">(</span>file_name<span class=\"token punctuation\">,</span> line_count<span class=\"token punctuation\">)</span><br />    <span class=\"token variable\">@file_name</span> <span class=\"token operator\">=</span> file_name<br />    <span class=\"token variable\">@line_count</span> <span class=\"token operator\">=</span> line_count<br />  <span class=\"token keyword\">end</span><br /><br />  attr_reader <span class=\"token symbol\">:line_count</span><br /><br />  <span class=\"token keyword\">def</span> <span class=\"token method-definition\"><span class=\"token function\">to_s</span></span><br />    <span class=\"token string-literal\"><span class=\"token string\">\"</span><span class=\"token interpolation\"><span class=\"token delimiter punctuation\">#{</span><span class=\"token content\"><span class=\"token variable\">@file_name</span></span><span class=\"token delimiter punctuation\">}</span></span><span class=\"token string\">: </span><span class=\"token interpolation\"><span class=\"token delimiter punctuation\">#{</span><span class=\"token content\"><span class=\"token variable\">@line_count</span></span><span class=\"token delimiter punctuation\">}</span></span><span class=\"token string\"> lines\"</span></span><br />  <span class=\"token keyword\">end</span><br /><span class=\"token keyword\">end</span><br /><br />path <span class=\"token operator\">=</span> <span class=\"token constant\">ARGV</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><br /><br />file_count <span class=\"token operator\">=</span> <span class=\"token number\">0</span><br />files_to_convert <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><br /><span class=\"token builtin\">Dir</span><span class=\"token punctuation\">.</span>glob<span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"</span><span class=\"token interpolation\"><span class=\"token delimiter punctuation\">#{</span><span class=\"token content\">path</span><span class=\"token delimiter punctuation\">}</span></span><span class=\"token string\">/**/*.dart\"</span></span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">do</span> <span class=\"token operator\">|</span>file_name<span class=\"token operator\">|</span><br />  file_count <span class=\"token operator\">+=</span> <span class=\"token number\">1</span><br />  first_line <span class=\"token operator\">=</span> <span class=\"token builtin\">File</span><span class=\"token punctuation\">.</span>open<span class=\"token punctuation\">(</span>file_name<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span><span class=\"token symbol\">:readline</span><span class=\"token punctuation\">)</span><br />  is_non_null_safe <span class=\"token operator\">=</span> first_line<span class=\"token punctuation\">.</span>start_with<span class=\"token operator\">?</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">'// @dart = 2.9'</span></span><span class=\"token punctuation\">)</span><br />  files_to_convert <span class=\"token operator\">&lt;&lt;</span> <span class=\"token class-name\">FileToConvert</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">new</span><span class=\"token punctuation\">(</span>file_name<span class=\"token punctuation\">,</span> <span class=\"token builtin\">File</span><span class=\"token punctuation\">.</span>foreach<span class=\"token punctuation\">(</span>file_name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>count<span class=\"token punctuation\">)</span> <span class=\"token keyword\">if</span> is_non_null_safe<br /><span class=\"token keyword\">end</span><br /><br />files_to_convert<span class=\"token punctuation\">.</span>sort_by<span class=\"token operator\">!</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span><span class=\"token symbol\">:line_count</span><span class=\"token punctuation\">)</span><br /><br />puts <span class=\"token string-literal\"><span class=\"token string\">\"Null safe percent: </span><span class=\"token interpolation\"><span class=\"token delimiter punctuation\">#{</span><span class=\"token content\"><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>file_count <span class=\"token operator\">-</span> files_to_convert<span class=\"token punctuation\">.</span>count<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>to_f <span class=\"token operator\">/</span> file_count<span class=\"token punctuation\">.</span>to_f <span class=\"token operator\">*</span> <span class=\"token number\">100</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>round<span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span></span><span class=\"token delimiter punctuation\">}</span></span><span class=\"token string\">%\"</span></span><br />puts <span class=\"token string-literal\"><span class=\"token string\">\"Number of files left to convert: </span><span class=\"token interpolation\"><span class=\"token delimiter punctuation\">#{</span><span class=\"token content\">files_to_convert<span class=\"token punctuation\">.</span>count</span><span class=\"token delimiter punctuation\">}</span></span><span class=\"token string\">\"</span></span><br />puts <span class=\"token string-literal\"><span class=\"token string\">''</span></span><br />puts <span class=\"token string-literal\"><span class=\"token string\">'10 Smallest files left to convert:'</span></span><br />files_to_convert<span class=\"token punctuation\">[</span><span class=\"token number\">0.</span><span class=\"token number\">.9</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">each</span> <span class=\"token keyword\">do</span> <span class=\"token operator\">|</span>file<span class=\"token operator\">|</span><br />  puts file<br /><span class=\"token keyword\">end</span></code></pre>\n<h3>4. The final push 🥅</h3>\n<p>You likely have a few huge files that no one wants to touch. Likely some God object definitions. There is no shortcut here. We have to approach it like some good old tech debt and buy some time to replace these.</p>\n<p>We are yet to make this final push. Will update this article if we have any learnings.</p>\n",
      "date_published": "2023-05-12T17:00:00Z"
    }
    ,
    {
      "id": "https://okmanideep.me/understanding-composition-and-side-effects/",
      "url": "https://okmanideep.me/understanding-composition-and-side-effects/",
      "title": "Understanding Composition and Side Effects",
      "content_html": "<style>\n.insight {\n    background: #3B4354;\n    border-radius: 3px;\n    padding: 12px;\n}\n.insight > :first-child {\n    margin-top: 0;\n}\n.insight > :last-child {\n    margin-bottom: 0;\n}\n</style>\n<p>Jetpack Compose is a <strong>Declarative UI Framework</strong> that allows us to define UI, state and side effects by declaring functions. A lot of them. Named and anonymous (lambdas). We will try and understand when does the framework invoke the functions we are declaring.</p>\n<p>Some of those functions we <em>declare</em> are <a href=\"https://developer.android.com/jetpack/compose/side-effects\">Side Effects</a>. Specifically we are going to look at <code>LaunchedEffect</code>, <code>SideEffect</code> and <code>DisposableEffect</code></p>\n<p>They look like this in the code</p>\n<pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token function\">LaunchedEffect</span><span class=\"token punctuation\">(</span><span class=\"token comment\">/*key(s)*/</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token comment\">/* effect that we are declaring as a lambda */</span><br /><span class=\"token punctuation\">}</span></code></pre>\n<p>When the above code is run, <code>LaunchedEffect</code> <a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/package-summary#LaunchedEffect(kotlin.Any,kotlin.coroutines.SuspendFunction1)\">the function</a> runs and registers the lambda we passed, to run it when it needs to be run. Well when exactly? We should get an idea very soon.</p>\n<p>Let's dive in.</p>\n<h2>🛠 Setup</h2>\n<p>A <code>@Composable</code> which sets up a bunch of logs inside Side Effects - <code>DisposableEffect</code>, <code>SideEffect</code> and <code>LaunchedEffect</code></p>\n<pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@Composable</span><br /><span class=\"token keyword\">fun</span> <span class=\"token function\">Effects</span><span class=\"token punctuation\">(</span><br />    logTag<span class=\"token operator\">:</span> String<span class=\"token punctuation\">,</span><br />    key<span class=\"token operator\">:</span> Any <span class=\"token operator\">=</span> logTag<span class=\"token punctuation\">,</span><br /><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token keyword\">val</span> tag <span class=\"token operator\">=</span> logTag<span class=\"token punctuation\">.</span><span class=\"token function\">padEnd</span><span class=\"token punctuation\">(</span><span class=\"token number\">25</span><span class=\"token punctuation\">)</span><br />    <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">tag</span></span><span class=\"token string\"> - Registering Effects\"</span></span><span class=\"token punctuation\">)</span><br />    <span class=\"token function\">LaunchedEffect</span><span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />        <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">tag</span></span><span class=\"token string\"> - LaunchedEffect\"</span></span><span class=\"token punctuation\">)</span><br />    <span class=\"token punctuation\">}</span><br />    <span class=\"token function\">DisposableEffect</span><span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />        <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">tag</span></span><span class=\"token string\"> - DisposableEffect\"</span></span><span class=\"token punctuation\">)</span><br />        onDispose <span class=\"token punctuation\">{</span><br />            <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">tag</span></span><span class=\"token string\"> - onDispose\"</span></span><span class=\"token punctuation\">)</span><br />        <span class=\"token punctuation\">}</span><br />    <span class=\"token punctuation\">}</span><br />    SideEffect <span class=\"token punctuation\">{</span><br />        <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">tag</span></span><span class=\"token string\"> - SideEffect\"</span></span><span class=\"token punctuation\">)</span><br />    <span class=\"token punctuation\">}</span><br /><span class=\"token punctuation\">}</span></code></pre>\n<p>And a <code>TrafficLight</code> that shows an emoji in <code>Text</code>. Also uses the <code>Effects</code> we defined above for logging</p>\n<pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@Composable</span><br /><span class=\"token keyword\">fun</span> <span class=\"token function\">TrafficLight</span><span class=\"token punctuation\">(</span><br />    lightEmoji<span class=\"token operator\">:</span> String<span class=\"token punctuation\">,</span><br />    modifier<span class=\"token operator\">:</span> Modifier <span class=\"token operator\">=</span> Modifier<br /><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token function\">Text</span><span class=\"token punctuation\">(</span>lightEmoji<span class=\"token punctuation\">,</span> fontSize <span class=\"token operator\">=</span> <span class=\"token number\">120</span><span class=\"token punctuation\">.</span>sp<span class=\"token punctuation\">,</span> modifier <span class=\"token operator\">=</span> modifier<span class=\"token punctuation\">)</span><br /><br />    <span class=\"token function\">Effects</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"TrafficLight(</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">lightEmoji</span></span><span class=\"token string\">)\"</span></span><span class=\"token punctuation\">)</span><br /><span class=\"token punctuation\">}</span></code></pre>\n<h2>Touch And Go</h2>\n<p>We are going to start by adding and removing this <code>TrafficLight</code> on touch as shown below</p>\n<pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@Composable</span><br /><span class=\"token keyword\">fun</span> <span class=\"token function\">TouchAndGo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token keyword\">var</span> isVisible <span class=\"token keyword\">by</span> remember <span class=\"token punctuation\">{</span> <span class=\"token function\">mutableStateOf</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><br />    <span class=\"token function\">Box</span><span class=\"token punctuation\">(</span><br />        contentAlignment <span class=\"token operator\">=</span> Alignment<span class=\"token punctuation\">.</span>Center<span class=\"token punctuation\">,</span><br />        modifier <span class=\"token operator\">=</span> Modifier<br />            <span class=\"token punctuation\">.</span><span class=\"token function\">fillMaxSize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><br />            <span class=\"token punctuation\">.</span><span class=\"token function\">clickable</span> <span class=\"token punctuation\">{</span><br />                <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"---Click---------------------\"</span></span><span class=\"token punctuation\">)</span><br />                isVisible <span class=\"token operator\">=</span> <span class=\"token operator\">!</span>isVisible<br />            <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span><br />    <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>isVisible<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />            <span class=\"token function\">TrafficLight</span><span class=\"token punctuation\">(</span>lightEmoji <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"🟢\"</span></span><span class=\"token punctuation\">)</span><br />        <span class=\"token punctuation\">}</span><br />    <span class=\"token punctuation\">}</span><br /><span class=\"token punctuation\">}</span></code></pre>\n<p>Initially we show nothing. On click, we show the green light 🟢.</p>\n<video width=\"320\" height=\"320\" autoplay=\"\" muted=\"\" loop=\"\">\n  <source src=\"https://s.okmanideep.me/touch-and-go.mp4\" type=\"video/mp4\" />\n</video>\n<p>Together, this is what we have got</p>\n<pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@Composable</span><br /><span class=\"token keyword\">fun</span> <span class=\"token function\">TouchAndGo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token keyword\">var</span> isVisible <span class=\"token keyword\">by</span> remember <span class=\"token punctuation\">{</span> <span class=\"token function\">mutableStateOf</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><br />    <span class=\"token function\">Box</span><span class=\"token punctuation\">(</span><br />        contentAlignment <span class=\"token operator\">=</span> Alignment<span class=\"token punctuation\">.</span>Center<span class=\"token punctuation\">,</span><br />        modifier <span class=\"token operator\">=</span> Modifier<br />            <span class=\"token punctuation\">.</span><span class=\"token function\">fillMaxSize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><br />            <span class=\"token punctuation\">.</span><span class=\"token function\">clickable</span> <span class=\"token punctuation\">{</span><br />                <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"---Click---------------------\"</span></span><span class=\"token punctuation\">)</span><br />                isVisible <span class=\"token operator\">=</span> <span class=\"token operator\">!</span>isVisible<br />            <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span><br />    <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>isVisible<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />            <span class=\"token function\">TrafficLight</span><span class=\"token punctuation\">(</span>lightEmoji <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"🟢\"</span></span><span class=\"token punctuation\">)</span><br />        <span class=\"token punctuation\">}</span><br />    <span class=\"token punctuation\">}</span><br /><span class=\"token punctuation\">}</span><br /><br /><span class=\"token annotation builtin\">@Composable</span><br /><span class=\"token keyword\">fun</span> <span class=\"token function\">TrafficLight</span><span class=\"token punctuation\">(</span><br />    lightEmoji<span class=\"token operator\">:</span> String<span class=\"token punctuation\">,</span><br />    modifier<span class=\"token operator\">:</span> Modifier <span class=\"token operator\">=</span> Modifier<br /><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token function\">Text</span><span class=\"token punctuation\">(</span>lightEmoji<span class=\"token punctuation\">,</span> fontSize <span class=\"token operator\">=</span> <span class=\"token number\">120</span><span class=\"token punctuation\">.</span>sp<span class=\"token punctuation\">,</span> modifier <span class=\"token operator\">=</span> modifier<span class=\"token punctuation\">)</span><br /><br />    <span class=\"token function\">Effects</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"TrafficLight(</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">lightEmoji</span></span><span class=\"token string\">)\"</span></span><span class=\"token punctuation\">)</span><br /><span class=\"token punctuation\">}</span><br /><br /><span class=\"token annotation builtin\">@Composable</span><br /><span class=\"token keyword\">fun</span> <span class=\"token function\">Effects</span><span class=\"token punctuation\">(</span><br />    logTag<span class=\"token operator\">:</span> String<span class=\"token punctuation\">,</span><br />    key<span class=\"token operator\">:</span> Any <span class=\"token operator\">=</span> logTag<span class=\"token punctuation\">,</span><br /><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token keyword\">val</span> tag <span class=\"token operator\">=</span> logTag<span class=\"token punctuation\">.</span><span class=\"token function\">padEnd</span><span class=\"token punctuation\">(</span><span class=\"token number\">25</span><span class=\"token punctuation\">)</span><br />    <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">tag</span></span><span class=\"token string\"> - Registering Effects\"</span></span><span class=\"token punctuation\">)</span><br />    <span class=\"token function\">LaunchedEffect</span><span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />        <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">tag</span></span><span class=\"token string\"> - LaunchedEffect\"</span></span><span class=\"token punctuation\">)</span><br />    <span class=\"token punctuation\">}</span><br />    <span class=\"token function\">DisposableEffect</span><span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />        <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">tag</span></span><span class=\"token string\"> - DisposableEffect\"</span></span><span class=\"token punctuation\">)</span><br />        onDispose <span class=\"token punctuation\">{</span><br />            <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">tag</span></span><span class=\"token string\"> - onDispose\"</span></span><span class=\"token punctuation\">)</span><br />        <span class=\"token punctuation\">}</span><br />    <span class=\"token punctuation\">}</span><br />    SideEffect <span class=\"token punctuation\">{</span><br />        <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">tag</span></span><span class=\"token string\"> - SideEffect\"</span></span><span class=\"token punctuation\">)</span><br />    <span class=\"token punctuation\">}</span><br /><span class=\"token punctuation\">}</span></code></pre>\n<p>Let's have a look at the logs</p>\n<pre><code>---Click---------------------\nTrafficLight(🟢)     - Registering Effects\nTrafficLight(🟢)     - DisposableEffect\nTrafficLight(🟢)     - SideEffect\nTrafficLight(🟢)     - LaunchedEffect\n---Click---------------------\nTrafficLight(🟢)     - onDispose\n</code></pre>\n<div class=\"insight\">\n<h3>✨ Insights</h3>\n<p>When a <code>Composable</code> enters composition:</p>\n<ul>\n<li>Our <code>@Composable</code> function runs first</li>\n<li>Then the <code>DisposableEffect</code>, the <code>SideEffect</code> and the <code>LaunchedEffect</code> in that order</li>\n</ul>\n<p>When a <code>Composable</code> exits composition:</p>\n<ul>\n<li>The <code>onDispose</code> of the corresponding <code>DisposableEffect</code> runs</li>\n</ul>\n</div>\n<p>Let's make it slightly more interesting. Let's add <code>Effects</code> above and below the <code>TrafficLight</code></p>\n<pre class=\"language-diff-kotlin\"><code class=\"language-diff-kotlin\"><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span><span class=\"token annotation builtin\">@Composable</span><br /><span class=\"token prefix unchanged\"> </span><span class=\"token keyword\">fun</span> <span class=\"token function\">TouchAndGo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token keyword\">var</span> isVisible <span class=\"token keyword\">by</span> remember <span class=\"token punctuation\">{</span> <span class=\"token function\">mutableStateOf</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token function\">Box</span><span class=\"token punctuation\">(</span><br /><span class=\"token prefix unchanged\"> </span>        <span class=\"token comment\">/*...*/</span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>isVisible<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /></span><span class=\"token inserted-sign inserted language-kotlin\"><span class=\"token prefix inserted\">+</span>            <span class=\"token function\">Effects</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"Pre - TrafficLight(🟢)\"</span></span><span class=\"token punctuation\">)</span><br /></span><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span>            <span class=\"token function\">TrafficLight</span><span class=\"token punctuation\">(</span>lightEmoji <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"🟢\"</span></span><span class=\"token punctuation\">)</span><br /></span><span class=\"token inserted-sign inserted language-kotlin\"><span class=\"token prefix inserted\">+</span>            <span class=\"token function\">Effects</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"Post - TrafficLight(🟢)\"</span></span><span class=\"token punctuation\">)</span><br /></span><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span>        <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span><span class=\"token punctuation\">}</span></span></code></pre>\n<p>So what do we have on the logs now?</p>\n<pre><code>---Click---------------------\nPre - TrafficLight(🟢)    - Registering Effects\nTrafficLight(🟢)          - Registering Effects\nPost - TrafficLight(🟢)   - Registering Effects\nPre - TrafficLight(🟢)    - DisposableEffect\nTrafficLight(🟢)          - DisposableEffect\nPost - TrafficLight(🟢)   - DisposableEffect\nPre - TrafficLight(🟢)    - SideEffect\nTrafficLight(🟢)          - SideEffect\nPost - TrafficLight(🟢)   - SideEffect\nPre - TrafficLight(🟢)    - LaunchedEffect\nTrafficLight(🟢)          - LaunchedEffect\nPost - TrafficLight(🟢)   - LaunchedEffect\n---Click---------------------\nPost - TrafficLight(🟢)   - onDispose\nTrafficLight(🟢)          - onDispose\nPre - TrafficLight(🟢)    - onDispose\n</code></pre>\n<div class=\"insight\">\n<h3>✨ Insights</h3>\n<p>On Entering Composition: </p>\n<ul>\n    <li>All the Side Effects run in the order they are declared / registered</li>\n    <li>Among the different Side Effects - <code>DisposableEffect</code>s run first, followed by <code>SideEffect</code>s, followed by <code>LaunchedEffect</code></li>\n</ul>\n<p>On Exiting Composition: </p>\n<ul>\n    <li><code>DisposableEffect</code>s are <i>disposed</i> in the <b>reverse</b> order they are declared / registered. <b>L</b>ast <b>I</b>n <b>F</b>irst <b>O</b>ut - LIFO. Like a stack!</li>\n</ul>\n</div>\n<hr />\n<h2>Stop And Go</h2>\n<p>Toggle between 🟢 and 🔴 on click</p>\n<pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@Composable</span><br /><span class=\"token keyword\">fun</span> <span class=\"token function\">StopAndGo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token keyword\">var</span> go <span class=\"token keyword\">by</span> remember <span class=\"token punctuation\">{</span> <span class=\"token function\">mutableStateOf</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><br /><br />    <span class=\"token function\">Box</span><span class=\"token punctuation\">(</span><br />        contentAlignment <span class=\"token operator\">=</span> Alignment<span class=\"token punctuation\">.</span>Center<span class=\"token punctuation\">,</span><br />        modifier <span class=\"token operator\">=</span> Modifier<br />            <span class=\"token punctuation\">.</span><span class=\"token function\">fillMaxSize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><br />            <span class=\"token punctuation\">.</span><span class=\"token function\">clickable</span> <span class=\"token punctuation\">{</span><br />                <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"---Click---------------------\"</span></span><span class=\"token punctuation\">)</span><br />                go <span class=\"token operator\">=</span> <span class=\"token operator\">!</span>go<br />            <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span><br />    <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />        <span class=\"token keyword\">val</span> light <span class=\"token operator\">=</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>go<span class=\"token punctuation\">)</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"🟢\"</span></span> <span class=\"token keyword\">else</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"🔴\"</span></span><br />        <span class=\"token function\">TrafficLight</span><span class=\"token punctuation\">(</span>lightEmoji <span class=\"token operator\">=</span> light<span class=\"token punctuation\">)</span><br />    <span class=\"token punctuation\">}</span><br /><span class=\"token punctuation\">}</span></code></pre>\n<video width=\"320\" height=\"320\" autoplay=\"\" muted=\"\" loop=\"\">\n  <source src=\"https://s.okmanideep.me/stop-and-go.mp4\" type=\"video/mp4\" />\n</video>\n<pre><code>TrafficLight(🟢)     - Registering Effects\nTrafficLight(🟢)     - DisposableEffect\nTrafficLight(🟢)     - SideEffect\nTrafficLight(🟢)     - LaunchedEffect\n---Click---------------------\nTrafficLight(🔴)     - Registering Effects\nTrafficLight(🟢)     - onDispose\nTrafficLight(🔴)     - DisposableEffect\nTrafficLight(🔴)     - SideEffect\nTrafficLight(🔴)     - LaunchedEffect\n</code></pre>\n<div class=\"insight\">\n<h3>✨ Insights</h3>\n<ul>\n<li>Incoming <code>DisposableEffect</code>s are <b>registered before</b> the outgoing <code>DisposableEffect</code>s are <b>disposed</b></li>\n<li>Incoming <code>DisposableEffect</code>s are <b>run after</b> the outgoing <code>DisposableEffect</code>s are <b>disposed</b></li>\n</ul>\n</div>\n<p>One might have expected this, because compose runtime figures out what are <em>incoming</em> and what are <em>outgoing</em> only after it runs / re-runs our <code>Composable</code> functions based on the new <code>State</code>.</p>\n<p>Nevertheless, this is an important aspect to keep in mind. Since this makes it safe for two <code>Composable</code>s that are never in composition together, to <code>acquire</code>/<code>release</code> to the same resource in their <code>DisposableEffect</code>s.</p>\n<h2>Stop Fade Go</h2>\n<p>More often than not, we animate our changes. Let's look at the order of execution when we add animation to the above example</p>\n<pre class=\"language-diff-kotlin\"><code class=\"language-diff-kotlin\"><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span><span class=\"token annotation builtin\">@Composable</span><br /><span class=\"token prefix unchanged\"> </span><span class=\"token keyword\">fun</span> <span class=\"token function\">StopFadeGo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token keyword\">var</span> go <span class=\"token keyword\">by</span> remember <span class=\"token punctuation\">{</span> <span class=\"token function\">mutableStateOf</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token function\">Box</span><span class=\"token punctuation\">(</span><br /><span class=\"token prefix unchanged\"> </span>        contentAlignment <span class=\"token operator\">=</span> Alignment<span class=\"token punctuation\">.</span>Center<span class=\"token punctuation\">,</span><br /><span class=\"token prefix unchanged\"> </span>        modifier <span class=\"token operator\">=</span> Modifier<br /><span class=\"token prefix unchanged\"> </span>            <span class=\"token punctuation\">.</span><span class=\"token function\">fillMaxSize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><br /><span class=\"token prefix unchanged\"> </span>            <span class=\"token punctuation\">.</span><span class=\"token function\">clickable</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>                <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"---Click---------------------\"</span></span><span class=\"token punctuation\">)</span><br /><span class=\"token prefix unchanged\"> </span>                go <span class=\"token operator\">=</span> <span class=\"token operator\">!</span>go<br /><span class=\"token prefix unchanged\"> </span>            <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>        <span class=\"token keyword\">val</span> light <span class=\"token operator\">=</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>go<span class=\"token punctuation\">)</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"🟢\"</span></span> <span class=\"token keyword\">else</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"🔴\"</span></span><br /></span><span class=\"token inserted-sign inserted language-kotlin\"><span class=\"token prefix inserted\">+</span>        <span class=\"token function\">Crossfade</span><span class=\"token punctuation\">(</span>targetState <span class=\"token operator\">=</span> light<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix inserted\">+</span>            <span class=\"token function\">TrafficLight</span><span class=\"token punctuation\">(</span>lightEmoji <span class=\"token operator\">=</span> it<span class=\"token punctuation\">)</span><br /><span class=\"token prefix inserted\">+</span>        <span class=\"token punctuation\">}</span><br /></span><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span>    <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span><span class=\"token punctuation\">}</span></span></code></pre>\n<pre><code>TrafficLight(🟢)     - Registering Effects\nTrafficLight(🟢)     - DisposableEffect\nTrafficLight(🟢)     - SideEffect\nTrafficLight(🟢)     - LaunchedEffect\n---Click---------------------\nTrafficLight(🔴)     - Registering Effects\nTrafficLight(🔴)     - DisposableEffect\nTrafficLight(🔴)     - SideEffect\nTrafficLight(🔴)     - LaunchedEffect\nTrafficLight(🟢)     - onDispose\n</code></pre>\n<div class=\"insight\">\n<h3>✨ Insights</h3>\n<p>When animated, the outgoing <code>DisposableEffect</code>s are disposed only after the animation is complete</p>\n</div>\n<p>Might feel obvious in hindsight. But it is important to keep in mind that since the <em>incoming</em> <code>DisposableEffect</code> runs before the <em>outgoing</em> disposes. This basically doesn't allow those <code>Composable</code>s to acquire/attach-to the same resource.</p>\n<hr />\n<h2>Ready Set Go</h2>\n<p>🔴 Ready -&gt; 🔴 Set -&gt; 🟢 Go on click</p>\n<pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@Composable</span><br /><span class=\"token keyword\">fun</span> <span class=\"token function\">ReadySetGo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token keyword\">var</span> count <span class=\"token keyword\">by</span> remember <span class=\"token punctuation\">{</span> <span class=\"token function\">mutableStateOf</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><br /><br />    <span class=\"token function\">Box</span><span class=\"token punctuation\">(</span><br />        contentAlignment <span class=\"token operator\">=</span> Alignment<span class=\"token punctuation\">.</span>Center<span class=\"token punctuation\">,</span><br />        modifier <span class=\"token operator\">=</span> Modifier<br />            <span class=\"token punctuation\">.</span><span class=\"token function\">fillMaxSize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><br />            <span class=\"token punctuation\">.</span><span class=\"token function\">clickable</span> <span class=\"token punctuation\">{</span><br />                <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"---Click---------------------\"</span></span><span class=\"token punctuation\">)</span><br />                count<span class=\"token operator\">++</span><br />            <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span><br />    <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />        <span class=\"token keyword\">val</span> step <span class=\"token operator\">=</span> count <span class=\"token operator\">%</span> <span class=\"token number\">3</span><br />        <span class=\"token keyword\">val</span> light <span class=\"token operator\">=</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>step <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"🟢\"</span></span> <span class=\"token keyword\">else</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"🔴\"</span></span><br />        <span class=\"token keyword\">val</span> message <span class=\"token operator\">=</span> <span class=\"token keyword\">when</span> <span class=\"token punctuation\">(</span>step<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />            <span class=\"token number\">1</span> <span class=\"token operator\">-></span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"Ready\"</span></span><br />            <span class=\"token number\">2</span> <span class=\"token operator\">-></span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"Set\"</span></span><br />            <span class=\"token number\">0</span> <span class=\"token operator\">-></span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"GO!\"</span></span><br />            <span class=\"token keyword\">else</span> <span class=\"token operator\">-></span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"Uh Oh!\"</span></span><br />        <span class=\"token punctuation\">}</span><br />        <span class=\"token function\">Column</span><span class=\"token punctuation\">(</span>horizontalAlignment <span class=\"token operator\">=</span> Alignment<span class=\"token punctuation\">.</span>CenterHorizontally<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />            <span class=\"token function\">TrafficLight</span><span class=\"token punctuation\">(</span>lightEmoji <span class=\"token operator\">=</span> light<span class=\"token punctuation\">)</span><br />            <span class=\"token function\">Spacer</span><span class=\"token punctuation\">(</span>modifier <span class=\"token operator\">=</span> Modifier<span class=\"token punctuation\">.</span><span class=\"token function\">height</span><span class=\"token punctuation\">(</span><span class=\"token number\">8</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><br />            <span class=\"token function\">Text</span><span class=\"token punctuation\">(</span>message<span class=\"token punctuation\">,</span> fontSize <span class=\"token operator\">=</span> <span class=\"token number\">36</span><span class=\"token punctuation\">.</span>sp<span class=\"token punctuation\">)</span><br />        <span class=\"token punctuation\">}</span><br />    <span class=\"token punctuation\">}</span><br /><span class=\"token punctuation\">}</span></code></pre>\n<video width=\"320\" height=\"320\" autoplay=\"\" muted=\"\" loop=\"\">\n  <source src=\"https://s.okmanideep.me/ready-set-go.mp4\" type=\"video/mp4\" />\n</video>\n<pre><code>TrafficLight(🔴)     - Registering Effects\nTrafficLight(🔴)     - DisposableEffect\nTrafficLight(🔴)     - SideEffect\nTrafficLight(🔴)     - LaunchedEffect\n---Click---------------------\n---Click---------------------\nTrafficLight(🟢)     - Registering Effects\nTrafficLight(🔴)     - onDispose\nTrafficLight(🟢)     - DisposableEffect\nTrafficLight(🟢)     - SideEffect\nTrafficLight(🟢)     - LaunchedEffect\n</code></pre>\n<blockquote>\n<p>Note that for both &quot;Ready&quot; and &quot;Set&quot; states, the light is 🔴</p>\n</blockquote>\n<div class=\"insight\">\n<h3>✨ Insights</h3>\n<p>Composition and Effects are skipped when the inputs don't change!</p>\n</div>\n<p>Just like <a href=\"https://developer.android.com/jetpack/compose/lifecycle#skipping\">the documentation says</a>. But what does &quot;inputs not changing&quot; really mean? Let's find out.</p>\n<p>Instead of passing in a <code>String</code>, let's create our own <code>class</code></p>\n<pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">class</span> <span class=\"token function\">Light</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> emoji<span class=\"token operator\">:</span> String<span class=\"token punctuation\">)</span></code></pre>\n<p>Update the <code>TrafficLight</code> and <code>ReadySetGo</code> to use <code>Light</code> instead of a <code>String</code></p>\n<pre class=\"language-diff-kotlin\"><code class=\"language-diff-kotlin\"><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span><span class=\"token annotation builtin\">@Composable</span><br /><span class=\"token prefix unchanged\"> </span><span class=\"token keyword\">fun</span> <span class=\"token function\">ReadySetGoClass</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token keyword\">var</span> count <span class=\"token keyword\">by</span> remember <span class=\"token punctuation\">{</span> <span class=\"token function\">mutableStateOf</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token function\">Box</span><span class=\"token punctuation\">(</span><br /><span class=\"token prefix unchanged\"> </span>        contentAlignment <span class=\"token operator\">=</span> Alignment<span class=\"token punctuation\">.</span>Center<span class=\"token punctuation\">,</span><br /><span class=\"token prefix unchanged\"> </span>        modifier <span class=\"token operator\">=</span> Modifier<br /><span class=\"token prefix unchanged\"> </span>            <span class=\"token punctuation\">.</span><span class=\"token function\">fillMaxSize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><br /><span class=\"token prefix unchanged\"> </span>            <span class=\"token punctuation\">.</span><span class=\"token function\">clickable</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>                <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"---Click---------------------\"</span></span><span class=\"token punctuation\">)</span><br /><span class=\"token prefix unchanged\"> </span>                count<span class=\"token operator\">++</span><br /><span class=\"token prefix unchanged\"> </span>            <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>        <span class=\"token keyword\">val</span> step <span class=\"token operator\">=</span> count <span class=\"token operator\">%</span> <span class=\"token number\">3</span><br /></span><span class=\"token inserted-sign inserted language-kotlin\"><span class=\"token prefix inserted\">+</span>        <span class=\"token keyword\">val</span> light <span class=\"token operator\">=</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>step <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token function\">Light</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"🟢\"</span></span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">else</span> <span class=\"token function\">Light</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"🔴\"</span></span><span class=\"token punctuation\">)</span><br /></span><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span>        <span class=\"token keyword\">val</span> message <span class=\"token operator\">=</span> <span class=\"token keyword\">when</span> <span class=\"token punctuation\">(</span>step<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>            <span class=\"token number\">1</span> <span class=\"token operator\">-></span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"Ready\"</span></span><br /><span class=\"token prefix unchanged\"> </span>            <span class=\"token number\">2</span> <span class=\"token operator\">-></span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"Set\"</span></span><br /><span class=\"token prefix unchanged\"> </span>            <span class=\"token number\">0</span> <span class=\"token operator\">-></span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"GO!\"</span></span><br /><span class=\"token prefix unchanged\"> </span>            <span class=\"token keyword\">else</span> <span class=\"token operator\">-></span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"Uh Oh!\"</span></span><br /><span class=\"token prefix unchanged\"> </span>        <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span>        <span class=\"token function\">Column</span><span class=\"token punctuation\">(</span>horizontalAlignment <span class=\"token operator\">=</span> Alignment<span class=\"token punctuation\">.</span>CenterHorizontally<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /></span><span class=\"token inserted-sign inserted language-kotlin\"><span class=\"token prefix inserted\">+</span>            <span class=\"token function\">TrafficLight</span><span class=\"token punctuation\">(</span>light<span class=\"token punctuation\">)</span><br /></span><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span>            <span class=\"token function\">Spacer</span><span class=\"token punctuation\">(</span>modifier <span class=\"token operator\">=</span> Modifier<span class=\"token punctuation\">.</span><span class=\"token function\">height</span><span class=\"token punctuation\">(</span><span class=\"token number\">8</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><br /><span class=\"token prefix unchanged\"> </span>            <span class=\"token function\">Text</span><span class=\"token punctuation\">(</span>message<span class=\"token punctuation\">,</span> fontSize <span class=\"token operator\">=</span> <span class=\"token number\">36</span><span class=\"token punctuation\">.</span>sp<span class=\"token punctuation\">)</span><br /><span class=\"token prefix unchanged\"> </span>        <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span><span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span><br /><span class=\"token prefix unchanged\"> </span><span class=\"token annotation builtin\">@Composable</span><br /><span class=\"token prefix unchanged\"> </span><span class=\"token keyword\">private</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">TrafficLight</span><span class=\"token punctuation\">(</span><br /></span><span class=\"token inserted-sign inserted language-kotlin\"><span class=\"token prefix inserted\">+</span>    light<span class=\"token operator\">:</span> Light<span class=\"token punctuation\">,</span><br /></span><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span>    modifier<span class=\"token operator\">:</span> Modifier <span class=\"token operator\">=</span> Modifier<br /><span class=\"token prefix unchanged\"> </span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /></span><span class=\"token inserted-sign inserted language-kotlin\"><span class=\"token prefix inserted\">+</span>    <span class=\"token keyword\">val</span> lightEmoji <span class=\"token operator\">=</span> light<span class=\"token punctuation\">.</span>emoji<br /></span><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span>    <span class=\"token function\">Text</span><span class=\"token punctuation\">(</span>lightEmoji<span class=\"token punctuation\">,</span> fontSize <span class=\"token operator\">=</span> <span class=\"token number\">120</span><span class=\"token punctuation\">.</span>sp<span class=\"token punctuation\">,</span> modifier <span class=\"token operator\">=</span> modifier<span class=\"token punctuation\">)</span><br /><span class=\"token prefix unchanged\"> </span><br /></span><span class=\"token inserted-sign inserted language-kotlin\"><span class=\"token prefix inserted\">+</span>    <span class=\"token function\">Effects</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"TrafficLight(</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">lightEmoji</span></span><span class=\"token string\">)\"</span></span><span class=\"token punctuation\">,</span> key <span class=\"token operator\">=</span> light<span class=\"token punctuation\">)</span><br /></span><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span><span class=\"token punctuation\">}</span></span></code></pre>\n<p>Here are the logs after the change</p>\n<pre><code>TrafficLight(🔴)     - Registering Effects\nTrafficLight(🔴)     - DisposableEffect\nTrafficLight(🔴)     - SideEffect\nTrafficLight(🔴)     - LaunchedEffect\n---Click---------------------\nTrafficLight(🔴)     - Registering Effects\nTrafficLight(🔴)     - onDispose\nTrafficLight(🔴)     - DisposableEffect\nTrafficLight(🔴)     - SideEffect\nTrafficLight(🔴)     - LaunchedEffect\n---Click---------------------\nTrafficLight(🟢)     - Registering Effects\nTrafficLight(🔴)     - onDispose\nTrafficLight(🟢)     - DisposableEffect\nTrafficLight(🟢)     - SideEffect\nTrafficLight(🟢)     - LaunchedEffect\n</code></pre>\n<p>Well what happened there!</p>\n<p>Our <code>Light</code> doesn't implement <code>.equals()</code>. The default implementation returns true only if they are the same instances. But we are creating a new instance every time. So compose runtime sees these as different inputs.</p>\n<p>Let's add a log to <code>equals()</code></p>\n<pre class=\"language-diff-kotlin\"><code class=\"language-diff-kotlin\"><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span><span class=\"token keyword\">private</span> <span class=\"token keyword\">class</span> <span class=\"token function\">Light</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> emoji<span class=\"token operator\">:</span> String<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token keyword\">override</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">equals</span><span class=\"token punctuation\">(</span>other<span class=\"token operator\">:</span> Any<span class=\"token operator\">?</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Boolean <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>other <span class=\"token keyword\">is</span> Light<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /></span><span class=\"token inserted-sign inserted language-kotlin\"><span class=\"token prefix inserted\">+</span>            <span class=\"token keyword\">val</span> result <span class=\"token operator\">=</span> <span class=\"token keyword\">super</span><span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span>other<span class=\"token punctuation\">)</span><br /><span class=\"token prefix inserted\">+</span>            <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">emoji</span></span><span class=\"token string\">.equals(</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">other<span class=\"token punctuation\">.</span>emoji</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">) = </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">result</span></span><span class=\"token string\">\"</span></span><span class=\"token punctuation\">)</span><br /></span><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span>            <span class=\"token keyword\">return</span> result<br /><span class=\"token prefix unchanged\"> </span>        <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span>        <span class=\"token keyword\">return</span> <span class=\"token keyword\">super</span><span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span>other<span class=\"token punctuation\">)</span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span><span class=\"token punctuation\">}</span></span></code></pre>\n<p>Haven't changed the implementation yet. Just added a log.</p>\n<p>The same logs as above but with <code>equals()</code></p>\n<pre><code>TrafficLight(🔴)     - Registering Effects\nTrafficLight(🔴)     - DisposableEffect\nTrafficLight(🔴)     - SideEffect\nTrafficLight(🔴)     - LaunchedEffect\n---Click---------------------\n🔴.equals(🔴) = false\nTrafficLight(🔴)     - Registering Effects\n🔴.equals(🔴) = false\n🔴.equals(🔴) = false\nTrafficLight(🔴)     - onDispose\nTrafficLight(🔴)     - DisposableEffect\nTrafficLight(🔴)     - SideEffect\nTrafficLight(🔴)     - LaunchedEffect\n---Click---------------------\n🔴.equals(🟢) = false\nTrafficLight(🟢)     - Registering Effects\n🔴.equals(🟢) = false\n🔴.equals(🟢) = false\nTrafficLight(🔴)     - onDispose\nTrafficLight(🟢)     - DisposableEffect\nTrafficLight(🟢)     - SideEffect\nTrafficLight(🟢)     - LaunchedEffect\n</code></pre>\n<p>So compose runtime compared the inputs. It observed that they are different (<code>.equals()</code> returned <code>false</code>), so ran the composable with the new input. It then compared the inputs again, to see if it has to run the <code>DisposableEffect</code> and the <code>LaunchedEffect</code> and ran them again because it received <code>false</code>.</p>\n<blockquote>\n<p>After all <code>DisposableEffect</code> and <code>LaunchedEffect</code> are <code>Composable</code> functions themselves</p>\n</blockquote>\n<p>Let's implement <code>equals()</code></p>\n<pre class=\"language-diff-kotlin\"><code class=\"language-diff-kotlin\"><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span><span class=\"token keyword\">private</span> <span class=\"token keyword\">class</span> <span class=\"token function\">Light</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> emoji<span class=\"token operator\">:</span> String<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token keyword\">override</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">equals</span><span class=\"token punctuation\">(</span>other<span class=\"token operator\">:</span> Any<span class=\"token operator\">?</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Boolean <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>other <span class=\"token keyword\">is</span> Light<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /></span><span class=\"token inserted-sign inserted language-kotlin\"><span class=\"token prefix inserted\">+</span>            <span class=\"token keyword\">val</span> result <span class=\"token operator\">=</span> emoji <span class=\"token operator\">==</span> other<span class=\"token punctuation\">.</span>emoji<br /></span><span class=\"token unchanged language-kotlin\"><span class=\"token prefix unchanged\"> </span>            <span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">emoji</span></span><span class=\"token string\">.equals(</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">other<span class=\"token punctuation\">.</span>emoji</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">) = </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">result</span></span><span class=\"token string\">\"</span></span><span class=\"token punctuation\">)</span><br /><span class=\"token prefix unchanged\"> </span>            <span class=\"token keyword\">return</span> result<br /><span class=\"token prefix unchanged\"> </span>        <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span>        <span class=\"token keyword\">return</span> <span class=\"token keyword\">super</span><span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span>other<span class=\"token punctuation\">)</span><br /><span class=\"token prefix unchanged\"> </span>    <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span><span class=\"token punctuation\">}</span></span></code></pre>\n<pre><code>TrafficLight(🔴)     - Registering Effects\nTrafficLight(🔴)     - DisposableEffect\nTrafficLight(🔴)     - SideEffect\nTrafficLight(🔴)     - LaunchedEffect\n---Click---------------------\n🔴.equals(🔴) = true\n---Click---------------------\n🔴.equals(🟢) = false\nTrafficLight(🟢)     - Registering Effects\n🔴.equals(🟢) = false\n🔴.equals(🟢) = false\nTrafficLight(🔴)     - onDispose\nTrafficLight(🟢)     - DisposableEffect\nTrafficLight(🟢)     - SideEffect\nTrafficLight(🟢)     - LaunchedEffect\n</code></pre>\n<p>Back to normal.</p>\n<p>Let's summarize all the insights</p>\n<div class=\"insight\">\n<h3>✨ Insights</h3>\n<p>➡️ On Entering Composition: </p>\n<ul>\n    <li>Our <code>Composable</code> function runs first</li>\n    <li>All the Side Effects run in the order they are declared / registered</li>\n    <li>Among the different Side Effects - <code>DisposableEffect</code>s run first, followed by <code>SideEffect</code>s, followed by <code>LaunchedEffect</code></li>\n</ul>\n<p>⬅️ On Exiting Composition: </p>\n<ul>\n    <li><code>DisposableEffect</code>s are <i>disposed</i> in the <b>reverse</b> order they are declared / registered. <b>L</b>ast <b>I</b>n <b>F</b>irst <b>O</b>ut - LIFO. Like a stack!</li>\n</ul>\n<p>🔀 When a composable is being replaced with another or recomposed with the new state:</p>\n<ul>\n<li>Incoming <code>DisposableEffect</code>s are <b>registered before</b> the outgoing <code>DisposableEffect</code>s are <b>disposed</b></li>\n<li>Incoming <code>DisposableEffect</code>s are <b>run after</b> the outgoing <code>DisposableEffect</code>s are <b>disposed</b></li>\n</ul>\n<p>💫 When animated, the outgoing <code>DisposableEffect</code>s are disposed only after the animation is complete.</p>\n<p>🚫 Composition and Effects are skipped when the inputs don't change. Inputs are compared using their <code>equals()</code> method</p>\n</div>\n",
      "date_published": "2022-04-01T18:00:00Z"
    }
    ,
    {
      "id": "https://okmanideep.me/dependency-management-in-multi-module-gradle-projects/",
      "url": "https://okmanideep.me/dependency-management-in-multi-module-gradle-projects/",
      "title": "Dependency management in multi-module gradle projects",
      "content_html": "<p>Google's approach in <a href=\"https://github.com/googlesamples/android-architecture-components/\">this google samples repo</a> seems to be tackling it very well. They actually do it across multiple projects but it applies for multiple modules as well. If you just have one module, don't bother doing this right now, but remember to do it when you decide to extract a module out.</p>\n<p>Our main objectives are to</p>\n<ul>\n<li>Minimise the effort required to update dependecies</li>\n<li>Maintain consistency in dependency versions across modules</li>\n</ul>\n<h2>What to do?</h2>\n<h4>Step 1</h4>\n<p>Declare your dependencies and versions at the root of the project.</p>\n<p><code>$PROJECT_ROOT/dependencies.gradle</code></p>\n<pre class=\"language-groovy\"><code class=\"language-groovy\">ext<span class=\"token punctuation\">.</span>versions <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">:</span><span class=\"token punctuation\">]</span><br /><br /><span class=\"token keyword\">def</span> versions <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">:</span><span class=\"token punctuation\">]</span><br /><br />versions<span class=\"token punctuation\">.</span>support_lib <span class=\"token operator\">=</span> <span class=\"token string\">'26.0.2'</span><br />versions<span class=\"token punctuation\">.</span>gson <span class=\"token operator\">=</span> <span class=\"token string\">'2.8.0'</span><br /><br />ext<span class=\"token punctuation\">.</span>versions <span class=\"token operator\">=</span> versions<br /><br />ext<span class=\"token punctuation\">.</span>deps <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">:</span><span class=\"token punctuation\">]</span><br /><span class=\"token keyword\">def</span> deps <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">:</span><span class=\"token punctuation\">]</span><br /><br /><span class=\"token keyword\">def</span> support_lib <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">:</span><span class=\"token punctuation\">]</span><br />support_lib<span class=\"token punctuation\">.</span>app_compat <span class=\"token operator\">=</span> <span class=\"token interpolation-string\"><span class=\"token string\">\"com.android.support:appcompat-v7:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">versions</span></span><span class=\"token string\">.support_lib\"</span></span><br />support_lib<span class=\"token punctuation\">.</span>recycler_view <span class=\"token operator\">=</span> <span class=\"token interpolation-string\"><span class=\"token string\">\"com.android.support:recyclerview-v7:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">versions</span></span><span class=\"token string\">.support_lib\"</span></span><br />deps<span class=\"token punctuation\">.</span>support_lib <span class=\"token operator\">=</span> support_lib<br /><br />deps<span class=\"token punctuation\">.</span>gson <span class=\"token operator\">=</span> <span class=\"token interpolation-string\"><span class=\"token string\">\"com.google.code.gson:gson:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$</span><span class=\"token expression\">versions</span></span><span class=\"token string\">.gson\"</span></span><br /><br />ext<span class=\"token punctuation\">.</span>deps <span class=\"token operator\">=</span> deps</code></pre>\n<p>Attaching <code>versions</code> and <code>deps</code> to extra user properties <code>ext</code> will allow you to access those variables all across the project</p>\n<h4>Step 2</h4>\n<p>Import the definitions at the top of root project's <code>buildScript</code> block</p>\n<p><code>$PROJECT_ROOT/build.gradle</code></p>\n<pre class=\"language-groovy\"><code class=\"language-groovy\">buildScript <span class=\"token punctuation\">{</span><br />  apply from<span class=\"token punctuation\">:</span> <span class=\"token string\">'dependencies.gradle'</span><br /><br />  <span class=\"token comment\">//left out for brevity...</span><br /><span class=\"token punctuation\">}</span></code></pre>\n<h4>Final step</h4>\n<p>Declare your module dependencies using the variables defined</p>\n<p><code>$PROJECT_ROOT/my-module/build.gradle</code></p>\n<pre class=\"language-groovy\"><code class=\"language-groovy\"><span class=\"token comment\">//left for brevity...</span><br />dependecies <span class=\"token punctuation\">{</span><br />  implementation deps<span class=\"token punctuation\">.</span>support_lib<span class=\"token punctuation\">.</span>app_compat<br />  implementation deps<span class=\"token punctuation\">.</span>support_lib<span class=\"token punctuation\">.</span>recycler_view<br />  implementation deps<span class=\"token punctuation\">.</span>gson<br /><span class=\"token punctuation\">}</span></code></pre>\n<h2>Approach</h2>\n<p>All we have done is <strong>remove duplication</strong> by reusing the version and dependency declarations done at one single place. Since all modules point to the same declaration, they all are in sync. And since there is only one declaration per dependency in the project, it is easy to find and update that one dependency.</p>\n<h2>IntelliJ doesn't help you much here</h2>\n<h4>Make your variable names easier to debug</h4>\n<p>Once you declare the variables, IntelliJ doesn't auto complete or suggest them else where when you are editing the gradle files. So make sure your variable name usages are proper and easily debuggable. That is intension behind using camel case here(YMMV).</p>\n<h4>Do not change all the dependencies at once</h4>\n<p>The error messages are not specific enough to figure out which variable name of dependency path you messed up. You can go ahead and define all the variables at once but add/use them one by one and sync your gradle file after each step to avoid frustrating debugging sessions.</p>\n<h2>Feedback</h2>\n<p>What do you think of this approach? Is there a better way? I am actually curious how this changes when we use kotlin to write gradle files. <a href=\"https://twitter.com/okmanideep\">Let me know</a> your feedback.</p>\n",
      "date_published": "2017-11-02T00:20:00Z"
    }
    ,
    {
      "id": "https://okmanideep.me/improve-your-android-build-times/",
      "url": "https://okmanideep.me/improve-your-android-build-times/",
      "title": "Improve your Android build times",
      "content_html": "<p>If you have the time to watch the video, go ahead. <a href=\"https://twitter.com/madisp\">Madis Pink</a> goes over each optimisation you can do very carefully and how you can profile the gradle build process to identify the bottlenecks of your builds. If not, go ahead do the changes mentioned below, which will take less than two minutes and enjoy a much smaller build times.</p>\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/AbNhen_zn-c\" frameborder=\"0\" allowfullscreen=\"\"></iframe>\n<h2>Optimisations</h2>\n<h4>The minSdk 21 trick</h4>\n<p>It doesn't matter your app is over the 65K method limit or not, enabling multiDex and having product flavors like this help a lot.</p>\n<pre class=\"language-groovy\"><code class=\"language-groovy\">productFlavors <span class=\"token punctuation\">{</span><br />    dev <span class=\"token punctuation\">{</span><br />        multiDexEnabled <span class=\"token boolean\">true</span><br />        minSdkVersion <span class=\"token number\">21</span><br />    <span class=\"token punctuation\">}</span><br />    prod <span class=\"token punctuation\">{</span><br />        multiDexEnabled <span class=\"token boolean\">true</span><br />        minSdkVersion <span class=\"token number\">15</span><br />    <span class=\"token punctuation\">}</span><br /><span class=\"token punctuation\">}</span></code></pre>\n<p>And also keep in mind that <strong>Instant Run</strong> has <a href=\"https://twitter.com/tornorbye/status/717446584284241921\">some overhead</a> on the dex method count in your debug builds, which might just make your method count go over the limit.</p>\n<p>On my machine for my project\n<code>./gradlew :app:assembleProdDebug</code> takes <strong>55.623s</strong> and <code>./gradlew :app:assembleDevDebug</code> takes <strong>12.41s</strong>!</p>\n<p>So yeah. Do it.</p>\n<h4>Use a Daemon</h4>\n<p>Using a daemon essentially means, gradle keeps a JVM and gradle instance running after the first build and reuses the same for subsequent builds. Android Studio <strong>already uses a daemon</strong> for every build that is triggered from the IDE, but this is very useful for builds triggered from the command line.</p>\n<p><strong>Dry Run</strong> without daemon</p>\n<pre class=\"language-sh\"><code class=\"language-sh\">./gradlew :app:assembleDebug --dry-run</code></pre>\n<p>Output:</p>\n<pre><code>BUILD SUCCESSFUL\n\nTotal time: 11.657 secs\n\nThis build could be faster, please consider using the Gradle Daemon: https://docs.gradle.org/2.10/userguide/gradle_daemon.html\n</code></pre>\n<h4>Enabling gradle daemon</h4>\n<p>In your <code>~/.gradle/gradle.properties</code></p>\n<pre><code>org.gradle.daemon=true\n</code></pre>\n<p><strong>Dry Run output after enabling daemon</strong></p>\n<pre><code>BUILD SUCCESSFUL\n\nTotal time: 1.757 secs\n</code></pre>\n<h4>Upgradle your gradle version</h4>\n<p>The gradle team is constantly optimising the build performance and it is wise to be using the latest version for the best performance. Here is how you change it<br />\nIn <code>&lt;Project Root&gt;/gradle/wrapper/</code><br />\nEdit <code>gradle-wrapper.properties</code> and upgrade gradle <code>distributionUrl</code> to the <a href=\"http://gradle.org/gradle-download/\">latest</a>.</p>\n<blockquote>\n<p>The difference will be substantially good if you are upgrading from or below <code>2.4</code></p>\n</blockquote>\n<h4>Use JDK 8</h4>\n<p>Groovy, being a dynamic language, can really benifit from the <code>invoke dynamic</code> instruction in Java 7 and above. So using JDK7 or JDK8 will certainly be helpful.</p>\n<ul>\n<li>Download and install <a href=\"http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html\">JDK 8</a></li>\n<li><code>Cmd+Shift+A</code> or <code>Ctrl+Shift+A</code>, type <code>Project Structure</code> and change <code>JDK Location</code> to JDK 8 location</li>\n</ul>\n<h4>Parallel Execution</h4>\n<p>If you have modules that are standalone, you can improve the build time a bit by enabling parallel execution.<br />\nIn your <code>./gradle/gradle.properties</code> or <code>&lt;Project Root&gt;/gradle.properties</code>, add this line</p>\n<pre><code>org.gradle.parallel=true\n</code></pre>\n<h2>Common Pitfalls</h2>\n<h4>Dynamic dependencies</h4>\n<p>Use definite version numbers for your dependencies in your gradle</p>\n<pre class=\"language-groovy\"><code class=\"language-groovy\"><span class=\"token comment\">//Do NOT do this</span><br />compile <span class=\"token string\">'com.google.code.gson:gson:2.+'</span><br /><br /><span class=\"token comment\">//Do this instead</span><br />compile <span class=\"token string\">'com.google.code.gson:gson:2.3'</span></code></pre>\n<p>This avoids the problem of gradle always making a network request to check for the latest version of the dependency</p>\n<h4>Avoid heavy computation</h4>\n<p>You can find snippets like this on stack overflow that aim to make versioning easier for you</p>\n<pre class=\"language-groovy\"><code class=\"language-groovy\"><span class=\"token keyword\">def</span> cmd <span class=\"token operator\">=</span> <span class=\"token string\">'git rev-list HEAD --first-parent --count'</span><br /><span class=\"token keyword\">def</span> gitVersion <span class=\"token operator\">=</span> cmd<span class=\"token punctuation\">.</span><span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>text<span class=\"token punctuation\">.</span><span class=\"token function\">trim</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toInteger</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><br /><br />android <span class=\"token punctuation\">{</span><br />  defaultConfig <span class=\"token punctuation\">{</span><br />    versionCode gitVersion<br />  <span class=\"token punctuation\">}</span><br /><span class=\"token punctuation\">}</span></code></pre>\n<p>The problem with this code is - gradle needs to count the number of commits for every build. For a large repo which has around <code>20000</code> commits, it takes around <strong>half a second</strong> to just count the number of commits.</p>\n<h4>That's it</h4>\n<p>After these optimisations your first build might take the same amount of time, but trust me your <strong>subsequent builds will be much faster</strong> overall.</p>\n<p>Also there is one more very important optimisation you can do</p>\n<h4>Get an SSD</h4>\n<p>Please do.</p>\n",
      "date_published": "2016-04-05T20:10:00Z"
    }
    ,
    {
      "id": "https://okmanideep.me/rxconfusions-part-1-map-and-flatmap/",
      "url": "https://okmanideep.me/rxconfusions-part-1-map-and-flatmap/",
      "title": "RxConfusions - Part 1 : Map and FlatMap",
      "content_html": "<p>If you don't know what RxJava is or you aren't comfortable with the terms <code>Observable</code>, <code>Observer</code>, <code>Operator</code> and <code>Subscriber</code>, I suggest you have a look at <a href=\"http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/\">Grokking RxJava</a> series by <a href=\"https://twitter.com/danlew42\">Dan Lew</a>.</p>\n<p>If you have surfed through some RxJava content on the web, you should have come accross the <code>map()</code> operator. It is exactly what you think it is. But you might have seen people using the <code>flatMap()</code> operator in similar senarios which might have confused you a bit. Let's use them both in a small example and observe the effects of these operators.</p>\n<p>Let's use this simple <code>Observer</code> for logging</p>\n<pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">onCompleted</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token class-name\">System</span><span class=\"token punctuation\">.</span>out<span class=\"token punctuation\">.</span><span class=\"token function\">println</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"onCompleted\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token punctuation\">}</span><br /><br /><span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">onError</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Throwable</span> e<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token class-name\">System</span><span class=\"token punctuation\">.</span>out<span class=\"token punctuation\">.</span><span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"onError: %s\\n\"</span><span class=\"token punctuation\">,</span> e<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token punctuation\">}</span><br /><br /><span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">onNext</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> s<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token class-name\">System</span><span class=\"token punctuation\">.</span>out<span class=\"token punctuation\">.</span><span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"onNext: %s\\n\"</span><span class=\"token punctuation\">,</span> s<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token punctuation\">}</span></code></pre>\n<h4>Simple use of map operator</h4>\n<pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">void</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> args<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token class-name\">Printer</span> printer <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Printer</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br />    <span class=\"token class-name\">String</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> names <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> <span class=\"token punctuation\">{</span><span class=\"token string\">\"John\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"Samuel\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"Micheal\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"Tom\"</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span><br />    printer<span class=\"token punctuation\">.</span><span class=\"token function\">printTitlesUsingMap</span><span class=\"token punctuation\">(</span>names<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token punctuation\">}</span><br /><br /><span class=\"token keyword\">private</span> <span class=\"token keyword\">void</span> <span class=\"token function\">printTitlesUsingMap</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> names<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token class-name\">Observable</span><span class=\"token punctuation\">.</span><span class=\"token function\">from</span><span class=\"token punctuation\">(</span>names<span class=\"token punctuation\">)</span><br />            <span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Printer</span><span class=\"token operator\">::</span><span class=\"token function\">getTitle</span><span class=\"token punctuation\">)</span><br />            <span class=\"token punctuation\">.</span><span class=\"token function\">subscribe</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token punctuation\">}</span><br /><br /><span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token class-name\">String</span> <span class=\"token function\">getTitle</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token keyword\">return</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">.</span><span class=\"token function\">format</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%s - %d\"</span><span class=\"token punctuation\">,</span> name<span class=\"token punctuation\">,</span> name<span class=\"token punctuation\">.</span><span class=\"token function\">length</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token punctuation\">}</span></code></pre>\n<p>Output :</p>\n<pre><code>onNext: John - 4\nonNext: Micheal - 7\nonNext: Tom - 3\nonNext: Samuel - 6\nonCompleted\n</code></pre>\n<p>Lets make it a little interesting</p>\n<pre class=\"language-diff-java\"><code class=\"language-diff-java\"><span class=\"token unchanged language-java\"><span class=\"token prefix unchanged\"> </span> <span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token class-name\">String</span> <span class=\"token function\">getTitle</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token class-name\">IllegalArgumentException</span><span class=\"token punctuation\">{</span><br /></span><span class=\"token inserted-sign inserted language-java\"><span class=\"token prefix inserted\">+</span>     <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Micheal\"</span><span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix inserted\">+</span>         <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">IllegalArgumentException</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Too many Micheals\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token prefix inserted\">+</span>     <span class=\"token punctuation\">}</span><br /></span><span class=\"token unchanged language-java\"><span class=\"token prefix unchanged\"> </span>     <span class=\"token keyword\">return</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">.</span><span class=\"token function\">format</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%s - %d\"</span><span class=\"token punctuation\">,</span> name<span class=\"token punctuation\">,</span> name<span class=\"token punctuation\">.</span><span class=\"token function\">length</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token prefix unchanged\"> </span> <span class=\"token punctuation\">}</span></span></code></pre>\n<p>Output :</p>\n<pre><code>onNext: John - 4\nonNext: Samuel - 6\nonError: java.lang.IllegalArgumentException: Too many Micheals\n</code></pre>\n<p>Even though there are too many Micheals, you don't want to stop printing once a Micheal arrives. You might be thinking lets use <code>filter()</code> to filter out <code>Micheal</code> but let us assume the printer doesn't know when <code>getTitle()</code> fails. Operators like <code>map()</code> can't change the flow items, they just modify the items which are emitted. This is when operators like <code>flatMap()</code> come in handly</p>\n<h4>Enter the FlatMap</h4>\n<pre class=\"language-diff-java\"><code class=\"language-diff-java\"><span class=\"token unchanged language-java\"><span class=\"token prefix unchanged\"> </span> <span class=\"token keyword\">private</span> <span class=\"token keyword\">void</span> <span class=\"token function\">printTitlesUsingFlatMap</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> names<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>     <span class=\"token class-name\">Observable</span><span class=\"token punctuation\">.</span><span class=\"token function\">from</span><span class=\"token punctuation\">(</span>names<span class=\"token punctuation\">)</span><br /><span class=\"token prefix unchanged\"> </span>             <span class=\"token punctuation\">.</span><span class=\"token function\">flatMap</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Printer</span><span class=\"token operator\">::</span><span class=\"token function\">getTitleObservable</span><span class=\"token punctuation\">)</span><br /><span class=\"token prefix unchanged\"> </span>             <span class=\"token punctuation\">.</span><span class=\"token function\">subscribe</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token prefix unchanged\"> </span> <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span> <br /><span class=\"token prefix unchanged\"> </span> <span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token class-name\">Observable</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">></span></span> <span class=\"token function\">getTitleObservable</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>     <span class=\"token keyword\">return</span> <span class=\"token class-name\">Observable</span><span class=\"token punctuation\">.</span><span class=\"token function\">create</span><span class=\"token punctuation\">(</span>subscriber <span class=\"token operator\">-></span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>         <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>subscriber<span class=\"token punctuation\">.</span><span class=\"token function\">isUnsubscribed</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /></span><span class=\"token inserted-sign inserted language-java\"><span class=\"token prefix inserted\">+</span>             <span class=\"token keyword\">try</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix inserted\">+</span>                 subscriber<span class=\"token punctuation\">.</span><span class=\"token function\">onNext</span><span class=\"token punctuation\">(</span><span class=\"token function\">getTitle</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token prefix inserted\">+</span>             <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">IllegalArgumentException</span> e<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix inserted\">+</span>                 <span class=\"token comment\">//do nothing</span><br /><span class=\"token prefix inserted\">+</span>             <span class=\"token punctuation\">}</span><br /><span class=\"token prefix inserted\">+</span>             subscriber<span class=\"token punctuation\">.</span><span class=\"token function\">onCompleted</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /></span><span class=\"token unchanged language-java\"><span class=\"token prefix unchanged\"> </span>         <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span>     <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token prefix unchanged\"> </span> <span class=\"token punctuation\">}</span></span></code></pre>\n<p>Notice that we are calling <code>subscriber.onComplete()</code> for every name. Guess the output... guessed it? Now have a look<br />\nOutput :</p>\n<pre><code>onNext: John - 4\nonNext: Samuel - 6\nonNext: Tom - 3\nonCompleted\n</code></pre>\n<p>Is that what you expected? Probably not. Now have a look at what happens if don't call <code>subscriber.onComplete()</code> when there is an exception.</p>\n<pre class=\"language-diff-java\"><code class=\"language-diff-java\"><span class=\"token unchanged language-java\"><span class=\"token prefix unchanged\"> </span> <span class=\"token keyword\">return</span> <span class=\"token class-name\">Observable</span><span class=\"token punctuation\">.</span><span class=\"token function\">create</span><span class=\"token punctuation\">(</span>subscriber <span class=\"token operator\">-></span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>     <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>subscriber<span class=\"token punctuation\">.</span><span class=\"token function\">isUnsubscribed</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>         <span class=\"token keyword\">try</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>             subscriber<span class=\"token punctuation\">.</span><span class=\"token function\">onNext</span><span class=\"token punctuation\">(</span><span class=\"token function\">getTitle</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /></span><span class=\"token inserted-sign inserted language-java\"><span class=\"token prefix inserted\">+</span>             subscriber<span class=\"token punctuation\">.</span><span class=\"token function\">onCompleted</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /></span><span class=\"token unchanged language-java\"><span class=\"token prefix unchanged\"> </span>         <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">IllegalArgumentException</span> e<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>             <span class=\"token comment\">//do nothing</span><br /><span class=\"token prefix unchanged\"> </span>         <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span>     <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span></code></pre>\n<p>Make a guess before you look at the output.</p>\n<pre><code>onNext: John - 4\nonNext: Samuel - 6\nonNext: Tom - 3\n</code></pre>\n<p>No <code>onComplete()</code> at all.<br />\nNow make a guess who is the <code>subscriber</code> to our <code>getTitleObservable()</code> function.</p>\n<blockquote>\n<p>The <code>flatMap()</code> operator is our subscriber</p>\n</blockquote>\n<p>If you are thiking - 'Wait, <code>flatMap()</code> is an <em>Operator</em> not a <em>Subscriber</em>', you should watch <a href=\"https://vimeo.com/144812843\">Demistifying RxJava Subscribers</a> by <a href=\"https://twitter.com/JakeWharton\">Jake Wharton</a>. Basically, <strong>everything</strong> is a subscriber.</p>\n<p><em>FlatMap</em> collects all the observables returned for each item in the stream and emits all the items emitted by those observables. Simply put, it is a <a href=\"https://github.com/ReactiveX/RxJava/blob/1.x/src/main/java/rx/Observable.java#L5204\">merge of all observables returned by your mapping function</a>.\nIt calls <code>onComplete()</code> only when all the observables are <em>completed</em>.</p>\n<p>In this example <code>getTitleObservale(&quot;Micheal&quot;)</code> wasn't completed. So <strong>FlatMap is waiting</strong> for it to complete(Yes, it is in the memory).</p>\n<p>Visualise what happened in the above example. Now think about the <code>map()</code> operator. If you feel like - 'They are two very different operators', then I have done my job. If you don't, <a href=\"https://twitter.com/okmanideep\">try confusing me as well</a>.</p>\n<p>I am no expert in this topic. Just sharing as I learn. Please <a href=\"https://twitter.com/okmanideep\">drop me a tweet</a> or a comment if I got anything wrong. And share it to people who you think will find this useful.</p>\n<h3>EDIT</h3>\n<p><a href=\"http://artemzin.com/blog/rxjava-defer-execution-of-function-via-fromcallable/\">Artem Zinnatullin</a>'s post suggests a better way to for our getTitleObservable().</p>\n<pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">return</span> <span class=\"token class-name\">Observable</span><span class=\"token punctuation\">.</span><span class=\"token function\">fromCallable</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token function\">getTitle</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre>\n<p>By using this method, you don't need to worry about calling the right functions to the subscriber. Thanks to <a href=\"https://www.reddit.com/r/androiddev/comments/3u5w0c/if_you_are_writing_observablecreate_theres_a_big/\">pakoito</a> for pointing that out.</p>\n",
      "date_published": "2015-12-01T20:10:00Z"
    }
    ,
    {
      "id": "https://okmanideep.me/clean-way-to-define-support-library-dependencies/",
      "url": "https://okmanideep.me/clean-way-to-define-support-library-dependencies/",
      "title": "Clean way to define support library dependencies",
      "content_html": "<p>As the support library started getting bigger with more tools in it, the team at google have suggested developers to pick and choose the individual pieces of the library in their dependencies. More recently our <code>build.gradle</code> files started to look like this</p>\n<pre class=\"language-groovy\"><code class=\"language-groovy\">dependencies <span class=\"token punctuation\">{</span><br />    compile <span class=\"token string\">'com.android.support:appcompat-v7:23.1.0'</span><br />    compile <span class=\"token string\">'com.android.support:design:23.1.0'</span><br />    compile <span class=\"token string\">'com.android.support:pallete-v7:23.1.0'</span><br />    compile <span class=\"token string\">'com.android.support:cardview-v7:23.1.0'</span><br />    compile <span class=\"token string\">'com.android.support:recyclerview-v7:23.1.0'</span><br /><span class=\"token punctuation\">}</span></code></pre>\n<p>So when a new release comes out, we have to change the version number in every single line. Chris Banes, from the Android developer relations team, in <a href=\"https://www.youtube.com/watch?v=ihQ16K8gSuQ&amp;t=17m58s\">Android Dev Summit 2015</a> has given this great tip to solve this problem.</p>\n<blockquote class=\"twitter-tweet\" lang=\"en\"><p lang=\"en\" dir=\"ltr\">This! <a href=\"https://twitter.com/hashtag/AndroidDev?src=hash\">#AndroidDev</a> <a href=\"https://twitter.com/hashtag/AndroidDevSummit?src=hash\">#AndroidDevSummit</a>&#10;🙏 <a href=\"https://twitter.com/chrisbanes\">@chrisbanes</a> <a href=\"https://t.co/v47Pm74ohj\">pic.twitter.com/v47Pm74ohj</a></p>&mdash; Manideep Polireddi (@okmanideep) <a href=\"https://twitter.com/okmanideep/status/669195097947377664\">November 24, 2015</a></blockquote>\n<script async=\"\" src=\"https://platform.twitter.com/widgets.js\" charset=\"utf-8\"></script>\n<p>Great! But there is a small <strong>catch</strong> here</p>\n<p><code>compile 'com.android.support:appcompat-v7:${supportLibVersion}'</code> <strong>doesn't work</strong><br />\n<code>compile &quot;com.android.support:appcompat-v7:${supportLibVersion}&quot;</code> <strong>WORKS!!!</strong></p>\n<p>If you haven't noticed yet, you should use <strong>double quotes</strong></p>\n<p>So the final code looks like this</p>\n<pre class=\"language-groovy\"><code class=\"language-groovy\">ext <span class=\"token punctuation\">{</span><br />    supportLibVersion <span class=\"token operator\">=</span> <span class=\"token string\">'23.1.1'</span><br /><span class=\"token punctuation\">}</span><br /><br />dependencies <span class=\"token punctuation\">{</span><br />    compile <span class=\"token interpolation-string\"><span class=\"token string\">\"com.android.support:appcompat-v7:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">supportLibVersion</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span><br />    compile <span class=\"token interpolation-string\"><span class=\"token string\">\"com.android.support:design:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">supportLibVersion</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span><br />    compile <span class=\"token interpolation-string\"><span class=\"token string\">\"com.android.support:pallete-v7:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">supportLibVersion</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span><br />    compile <span class=\"token interpolation-string\"><span class=\"token string\">\"com.android.support:cardview-v7:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">supportLibVersion</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span><br />    compile <span class=\"token interpolation-string\"><span class=\"token string\">\"com.android.support:recyclerview-v7:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">supportLibVersion</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span><br /><span class=\"token punctuation\">}</span></code></pre>\n<p>By the way, Android Studio is intelligent enough that it will suggest you to update the version when there is a new one out, even in the above format. All hail IntelliJ.</p>\n",
      "date_published": "2015-11-23T20:10:00Z"
    }
    ,
    {
      "id": "https://okmanideep.me/permissions-in-marshmallow/",
      "url": "https://okmanideep.me/permissions-in-marshmallow/",
      "title": "Permissions in marshmallow",
      "content_html": "<p>I expect you to first go and have a look at this page in the <a href=\"http://developer.android.com/training/permissions/requesting.html\">Android Bible</a> about permissions in marshmallow. Especially have a look at how to:</p>\n<ul>\n<li>Request the permissions you need</li>\n<li>Handle the permissions request response</li>\n</ul>\n<h4>Requesting for permission</h4>\n<p>You might have seen a code snippet like below in the training page.</p>\n<pre class=\"language-java\"><code class=\"language-java\"><span class=\"token comment\">// Here, thisActivity is the current activity</span><br /><span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">ContextCompat</span><span class=\"token punctuation\">.</span><span class=\"token function\">checkSelfPermission</span><span class=\"token punctuation\">(</span>thisActivity<span class=\"token punctuation\">,</span><br />                <span class=\"token class-name\">Manifest</span><span class=\"token punctuation\">.</span>permission<span class=\"token punctuation\">.</span><span class=\"token constant\">READ_CONTACTS</span><span class=\"token punctuation\">)</span><br />        <span class=\"token operator\">!=</span> <span class=\"token class-name\">PackageManager</span><span class=\"token punctuation\">.</span><span class=\"token constant\">PERMISSION_GRANTED</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token comment\">// Should we show an explanation?</span><br />    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">ActivityCompat</span><span class=\"token punctuation\">.</span><span class=\"token function\">shouldShowRequestPermissionRationale</span><span class=\"token punctuation\">(</span>thisActivity<span class=\"token punctuation\">,</span><br />            <span class=\"token class-name\">Manifest</span><span class=\"token punctuation\">.</span>permission<span class=\"token punctuation\">.</span><span class=\"token constant\">READ_CONTACTS</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />        <span class=\"token comment\">//show user the reason for permission</span><br />    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span><br />        <span class=\"token comment\">//request permission</span><br />    <span class=\"token punctuation\">}</span><br /><span class=\"token punctuation\">}</span></code></pre>\n<h3>Pay Attention</h3>\n<p>Lets just dive into the only tricky part here - <code>shouldShowRequestPermissionRationale()</code> returns</p>\n<ul>\n<li><strong>true</strong> if\n<ul>\n<li>The app has requested this permission previously and the user denied the request <strong>in the dialog</strong></li>\n<li>User has toggled off the permission <strong>in the settings</strong> (<em>Even if the app hasn't requested the permission yet, if the user just has toggled the switch on and off in the settings page, you are expected to show the rationale</em>)</li>\n</ul>\n</li>\n<li><strong>false</strong> if\n<ul>\n<li>The app didn't request for this permission yet</li>\n<li>The user denied the permission and chose <strong>Don't ask again</strong> option</li>\n<li>The device policy prohibits the app from having that permission (<em>Mostly in enterprise cenarios</em>)</li>\n</ul>\n</li>\n</ul>\n<h3>Consider this possible case</h3>\n<p>The above code works pretty much in most practical cases. Let us consider this case:</p>\n<ul>\n<li>The user has chosen <strong>Don't ask again</strong> for contacts access in the past (<em>which will most probably never happen if you have requested permissions gracefully and if the user made the decision conciously</em>)</li>\n<li>And now the user wants to send a contact to his friend</li>\n</ul>\n<p>There is no way to detect using the above code that we were denied the permission, and ask him to grant the permission via application settings.</p>\n<h3>The way out</h3>\n<p>Check for <code>shouldShowRequestPermissionRationale()</code> before and after asking permission. If it returns false both the times then the user chose 'Don't ask again' in the past or the device policy doesn't allow for that permission.</p>\n<pre class=\"language-diff-java\"><code class=\"language-diff-java\"><span class=\"token unchanged language-java\"><span class=\"token prefix unchanged\"> </span> <span class=\"token keyword\">boolean</span> before<span class=\"token punctuation\">,</span> after<span class=\"token punctuation\">;</span><br /><span class=\"token prefix unchanged\"> </span> <br /><span class=\"token prefix unchanged\"> </span> <span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">requestContactsPermission</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>     <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">ContextCompat</span><span class=\"token punctuation\">.</span><span class=\"token function\">checkSelfPermission</span><span class=\"token punctuation\">(</span>thisActivity<span class=\"token punctuation\">,</span><br /><span class=\"token prefix unchanged\"> </span>                     <span class=\"token class-name\">Manifest</span><span class=\"token punctuation\">.</span>permission<span class=\"token punctuation\">.</span><span class=\"token constant\">READ_CONTACTS</span><span class=\"token punctuation\">)</span><br /><span class=\"token prefix unchanged\"> </span>             <span class=\"token operator\">!=</span> <span class=\"token class-name\">PackageManager</span><span class=\"token punctuation\">.</span><span class=\"token constant\">PERMISSION_GRANTED</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>         <span class=\"token comment\">// Should we show an explanation?</span><br /></span><span class=\"token inserted-sign inserted language-java\"><span class=\"token prefix inserted\">+</span>         before <span class=\"token operator\">=</span> <span class=\"token class-name\">ActivityCompat</span><span class=\"token punctuation\">.</span><span class=\"token function\">shouldShowRequestPermissionRationale</span><span class=\"token punctuation\">(</span>thisActivity<span class=\"token punctuation\">,</span><br /><span class=\"token prefix inserted\">+</span>                 <span class=\"token class-name\">Manifest</span><span class=\"token punctuation\">.</span>permission<span class=\"token punctuation\">.</span><span class=\"token constant\">READ_CONTACTS</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token prefix inserted\">+</span>         <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>before<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /></span><span class=\"token unchanged language-java\"><span class=\"token prefix unchanged\"> </span>             <span class=\"token comment\">//show user the reason for permission</span><br /><span class=\"token prefix unchanged\"> </span>         <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>             <span class=\"token comment\">//request permission</span><br /><span class=\"token prefix unchanged\"> </span>         <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span>     <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span> <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span> <br /><span class=\"token prefix unchanged\"> </span> <span class=\"token annotation punctuation\">@Override</span><br /><span class=\"token prefix unchanged\"> </span> <span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">onRequestPermissionsResult</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> requestCode<span class=\"token punctuation\">,</span><br /><span class=\"token prefix unchanged\"> </span>         <span class=\"token class-name\">String</span> permissions<span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> grantResults<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>     <span class=\"token keyword\">switch</span> <span class=\"token punctuation\">(</span>requestCode<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>         <span class=\"token keyword\">case</span> <span class=\"token constant\">MY_PERMISSIONS_REQUEST_READ_CONTACTS</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>             <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>grantResults<span class=\"token punctuation\">.</span>length <span class=\"token operator\">></span> <span class=\"token number\">0</span><br /><span class=\"token prefix unchanged\"> </span>                 <span class=\"token operator\">&amp;&amp;</span> grantResults<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> <span class=\"token class-name\">PackageManager</span><span class=\"token punctuation\">.</span><span class=\"token constant\">PERMISSION_GRANTED</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br /><span class=\"token prefix unchanged\"> </span>                 <span class=\"token comment\">// permission was granted, yay! Do the</span><br /><span class=\"token prefix unchanged\"> </span>                 <span class=\"token comment\">// contacts-related task you need to do.</span><br /><span class=\"token prefix unchanged\"> </span>             <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span><br /></span><span class=\"token inserted-sign inserted language-java\"><span class=\"token prefix inserted\">+</span>                 after <span class=\"token operator\">=</span> <span class=\"token class-name\">ActivityCompat</span><span class=\"token punctuation\">.</span><span class=\"token function\">shouldShowRequestPermissionRationale</span><span class=\"token punctuation\">(</span><br /><span class=\"token prefix inserted\">+</span>                 thisActivity<span class=\"token punctuation\">,</span><br /><span class=\"token prefix inserted\">+</span>                 <span class=\"token class-name\">Manifest</span><span class=\"token punctuation\">.</span>permission<span class=\"token punctuation\">.</span><span class=\"token constant\">READ_CONTACTS</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token prefix inserted\">+</span>                 <span class=\"token keyword\">boolean</span> goToSettings <span class=\"token operator\">=</span> <span class=\"token operator\">!</span><span class=\"token punctuation\">(</span>after <span class=\"token operator\">||</span> before<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token prefix inserted\">+</span>                 <span class=\"token function\">showRationale</span><span class=\"token punctuation\">(</span>goToSettings<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /></span><span class=\"token unchanged language-java\"><span class=\"token prefix unchanged\"> </span>             <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span>             <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span><br /><span class=\"token prefix unchanged\"> </span>         <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span>     <span class=\"token punctuation\">}</span><br /><span class=\"token prefix unchanged\"> </span> <span class=\"token punctuation\">}</span></span></code></pre>\n<p>If both <code>before</code> and <code>after</code> are <code>false</code>, then show the user a dialog explaining that we need the contacts permission with a 'GO TO SETTINGS' button. On click take him to your application in the settings like this :</p>\n<pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">void</span> <span class=\"token function\">goToSettings</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><br />    <span class=\"token class-name\">Intent</span> intent <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Intent</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br />    intent<span class=\"token punctuation\">.</span><span class=\"token function\">setAction</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Settings</span><span class=\"token punctuation\">.</span><span class=\"token constant\">ACTION_APPLICATION_DETAILS_SETTINGS</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br />    <span class=\"token class-name\">Uri</span> uri <span class=\"token operator\">=</span> <span class=\"token class-name\">Uri</span><span class=\"token punctuation\">.</span><span class=\"token function\">parse</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"package:\"</span> <span class=\"token operator\">+</span> <span class=\"token function\">getPackageName</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br />    intent<span class=\"token punctuation\">.</span><span class=\"token function\">setData</span><span class=\"token punctuation\">(</span>uri<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br />    <span class=\"token function\">startActivity</span><span class=\"token punctuation\">(</span>intent<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><br /><span class=\"token punctuation\">}</span></code></pre>\n",
      "date_published": "2015-11-14T20:10:00Z"
    }
    
  ]
}
