Jekyll2018-03-28T09:01:11+05:30https://chaitanyapramod.com/Chaitanya PramodChaitanya Pramodiam@chaitanyapramod.comhttps://chaitanyapramod.com/Demystifying Butterknife2018-03-25T20:00:00+05:302018-03-25T20:00:00+05:30https://chaitanyapramod.com/blog/demystifying-butterknife<p>As an Android developer, you’re surely heard of Butterknife, may be even used it in countless projects yourself. Have you ever wondered what is behind the magical API of Butterknife. In this post, we unveil the magic and deconstruct its code.</p>
<hr />
<p>Butterknife is majorly composed of three pieces</p>
<ul>
<li><a href="#annotations">annotations</a></li>
<li><a href="#annotation-processor">annotation processor</a></li>
<li><a href="#runtime-library">runtime library</a></li>
</ul>
<h2 id="annotations">Annotations</h2>
<p>Defines all the <code class="highlighter-rouge">BindView</code> annotation and the like that you use on fields and methods in view code. You can see them all <a href="https://github.com/JakeWharton/butterknife/tree/8.8.1/butterknife-annotations/src/main/java/butterknife">here</a>.</p>
<noscript><pre>400: Invalid request
</pre></noscript>
<script src="https://gist.github.com/d42925a0ec25c70ea3b701ab5e83ae30.js"> </script>
<h2 id="annotation-processor">Annotation processor</h2>
<p>This is the most interesting part of Butterknife. The implementation is simple(ish). The processor <a href="https://github.com/JakeWharton/butterknife/blob/8.8.1/butterknife-compiler/src/main/java/butterknife/compiler/ButterKnifeProcessor.java#L164-L170">says it’s interested</a> in all the Butterknife annotations. Then the compiler <a href="https://github.com/JakeWharton/butterknife/blob/8.8.1/butterknife-compiler/src/main/java/butterknife/compiler/ButterKnifeProcessor.java#L193-L209">calls the processor</a> with all the elements annotated with these annotations. It creates the <code class="highlighter-rouge">XActivity_ViewBinding</code> class.</p>
<p>Here is a <a href="https://github.com/ChaitanyaPramod/ButterknifeDemo/blob/master/build/generated/source/apt/release/com/chaitanyapramod/butterknifedemo/MainActivity_ViewBinding.java">sample _ViewBinding class</a> generated by the processor.</p>
<noscript><pre>400: Invalid request
</pre></noscript>
<script src="https://gist.github.com/5e44378e105f6f0f33ccc8b3043a0d91.js?file=GeneratedViewBinding.java"> </script>
<p>Let’s focus on the <code class="highlighter-rouge">BindView</code> annotation, others behave similarly (listeners are slightly different). The crux of <code class="highlighter-rouge">parseBindView</code> is in <a href="https://github.com/JakeWharton/butterknife/blob/8.8.1/butterknife-compiler/src/main/java/butterknife/compiler/ButterKnifeProcessor.java#L475-L499">lines 475-499</a>.</p>
<noscript><pre>400: Invalid request
</pre></noscript>
<script src="https://gist.github.com/5e44378e105f6f0f33ccc8b3043a0d91.js?file=ButterKnifeProcessor-parseBindView.java"> </script>
<p>Listeners are implemented with little more complexity, mainly in <code class="highlighter-rouge">parseListenerAnnotation</code>, specifically <a href="https://github.com/JakeWharton/butterknife/blob/8.8.1/butterknife-compiler/src/main/java/butterknife/compiler/ButterKnifeProcessor.java#L1139-L1164">lines 1139-1164</a> and <a href="https://github.com/JakeWharton/butterknife/blob/8.8.1/butterknife-compiler/src/main/java/butterknife/compiler/ButterKnifeProcessor.java#L1204-L1213">1204-1213</a>. If we skip all the error-checking, the method <code class="highlighter-rouge">parseListenerAnnotation</code> matches the parameters from the Android listener which are used in the bound method and passes off the required params to <code class="highlighter-rouge">BindingSet.Builder#addMethod</code>.</p>
<noscript><pre>400: Invalid request
</pre></noscript>
<script src="https://gist.github.com/5e44378e105f6f0f33ccc8b3043a0d91.js?file=ButterKnifeProcessor-parseListenerAnnotation.java"> </script>
<p>Both these methods collect all the bindings into a <code class="highlighter-rouge">BindingSet</code> per type. Once a <code class="highlighter-rouge">Type</code> is processed, all these bindings are flushed to a <code class="highlighter-rouge">JavaFile</code> <code class="highlighter-rouge">X_ViewBinding.java</code></p>
<noscript><pre>400: Invalid request
</pre></noscript>
<script src="https://gist.github.com/fe42973e8c983563c86ade8d070daa7f.js"> </script>
<p>See Jake Wharton’s <a href="https://speakerdeck.com/jakewharton/annotation-processing-boilerplate-destruction-square-waterloo-2014">talk on Annotation Processor</a> to get more details of how one is built.</p>
<h2 id="runtime-library">Runtime library</h2>
<p>This is a utility library and some sugar. The utilities are used from the generated code and the <code class="highlighter-rouge">Butterknife</code> class. When you call <code class="highlighter-rouge">Butterknife.bind()</code>, it reflectively loads the processor-generated class, which is named <code class="highlighter-rouge">your-view-class-name + "_ViewBinding"</code> and constructs an instance of the class.</p>
<noscript><pre>400: Invalid request
</pre></noscript>
<script src="https://gist.github.com/5e44378e105f6f0f33ccc8b3043a0d91.js?file=Butterknife-createBinding.java"> </script>
<p>The <code class="highlighter-rouge">Butterknife</code> class is not really required to make use of the binder. In fact, it adds runtime reflection cost. You can instead use the generated class directly. This is the approach Dagger 2 has taken as well.</p>
<noscript><pre>400: Invalid request
</pre></noscript>
<script src="https://gist.github.com/5e44378e105f6f0f33ccc8b3043a0d91.js?file=NoReflection.java"> </script>
<h2 id="bonus-the-gradle-plugin">Bonus: The Gradle plugin</h2>
<p>The gradle plugin has a very simple function. It lets you use Butterknife in library modules. But why can’t you use Butterknife in library modules like regular application modules? Because the element value in an annotation can only be a constant value for primitive types<sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup><sup id="fnref:2"><a href="#fn:2" class="footnote">2</a></sup>. But the <code class="highlighter-rouge">R</code> class generated by Android Gradle plugin doesn’t make the ID values constant in library modules. If libraries had their resource IDs final, then the IDs could collide when building the final APK. So your compile step will complain loudly if you write</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@BindView</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">id</span><span class="o">.</span><span class="na">viewid</span><span class="o">)</span> <span class="n">View</span> <span class="n">idView</span><span class="o">;</span>
</code></pre></div></div>
<p>You could not use Butterknife in library modules earlier, that is until Gautam Korlam <a href="https://github.com/JakeWharton/butterknife/pull/613">contributed</a> a Gradle plugin which clones <code class="highlighter-rouge">R</code> as <code class="highlighter-rouge">R2</code> with final values for resources. Now you can use <code class="highlighter-rouge">@BindView(R2.id.viewid) View idView</code> in library modules without worry. Most of the interesting work is done in the <a href="https://github.com/JakeWharton/butterknife/blob/8.8.1/butterknife-gradle-plugin/src/main/java/butterknife/plugin/FinalRClassBuilder.java">class <code class="highlighter-rouge">FinalRClassBuilder</code></a>.</p>
<noscript><pre>400: Invalid request
</pre></noscript>
<script src="https://gist.github.com/5e44378e105f6f0f33ccc8b3043a0d91.js?file=FinalRClassBuilder.java"> </script>
<hr />
<p>I hope you’re now comfortable venturing into the source code of Butterknife armed with this knowledge.</p>
<p>Tip: Install <a href="https://chrome.google.com/webstore/detail/insightio-for-github/pmhfgjjhhomfplgmbalncpcohgeijonh">Insight.io for Github</a> to add IDE-like navigation capabilities to Github for pleasant code reading.</p>
<p>Look out for the next post where we would be building our own version of Butterknife from scratch.</p>
<hr />
<p><small>Thanks to <a href="https://1bucketlist.blogspot.com">Yashasvi Girdhar</a> for reading drafts of the post.</small></p>
<div class="footnotes">
<ol>
<li id="fn:1">
<p><a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28">https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28</a> <a href="#fnref:1" class="reversefootnote">↩</a></p>
</li>
<li id="fn:2">
<p><a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-ElementValue">https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-ElementValue</a> <a href="#fnref:2" class="reversefootnote">↩</a></p>
</li>
</ol>
</div>Chaitanya Pramodiam@chaitanyapramod.comhttps://chaitanyapramod.com/Walk through of Butterknife codebaseThe Indespensable Document for the Modern Manager2018-03-11T14:00:00+05:302018-03-11T14:00:00+05:30https://chaitanyapramod.com/blog/indispensable-document-for-modern-manager<p>I love the idea of writing a user guide on oneself. As a manager, you can share your thoughts, expectations, style of communication, personality as relevant for team members. This is extremely scalable and quite valuable to self and team members. Some of the questions from team can be answered right here, thus avoiding synchronous discussions.</p>
<p>via <a href="https://www.getrevue.co/profile/cmccarrick/issues/tech-leadership-weekly-issue-94-96861">Tech Leadership Weekly</a></p>Chaitanya Pramodiam@chaitanyapramod.comhttps://chaitanyapramod.com/User guide is one of the most powerful ideas for managersThe Internet Tidal Wave2018-02-25T09:00:00+05:302018-02-25T09:00:00+05:30https://chaitanyapramod.com/blog/internet-tidal-wave<p>Bill Gates wrote this fascinating memo to his staff in 1995. It predicts the evolution of internet ecosystem, how almost every service would be touched by it and why it was super-important to be an internet player.</p>
<p>via <a href="http://amzn.to/2GGuS2d">Deep Work</a></p>Chaitanya Pramodiam@chaitanyapramod.comhttps://chaitanyapramod.com/Bill Gates's memo predicting the direction of internet evolution and the peril of not being an internet-playerDagger 2.0 Proposal2018-02-01T11:30:00+05:302018-02-01T11:30:00+05:30https://chaitanyapramod.com/blog/dagger-2-proposal<p>Found this beatiful document from Greg Kick making a proposal for fully statically resolved dependency injection framework on Dagger 1 Github issues.</p>
<p>This proposal is historically significant as it brings in a new generation of java dependency injection framework which is completely code generated. This avoids reflection altogether which is expensive in terms of CPU cycles (and much more so on Android).</p>
<p>via <a href="https://github.com/square/dagger/issues/366">https://github.com/square/dagger/issues/366</a></p>Chaitanya Pramodiam@chaitanyapramod.comhttps://chaitanyapramod.com/Historically significant document proposing Dagger 2 design from Greg KickUnderstanding Elasticsearch bottom up2018-02-01T11:00:00+05:302018-02-01T11:00:00+05:30https://chaitanyapramod.com/blog/understanding-es<h2 id="understanding-elasticsearch">Understanding Elasticsearch</h2>
<ul>
<li><a href="https://www.elastic.co/blog/found-elasticsearch-from-the-bottom-up">https://www.elastic.co/blog/found-elasticsearch-from-the-bottom-up</a></li>
<li>Inverted index
<ul>
<li>Dictionary contains term and frequency, postings contain documents (IDs)</li>
<li>Index term being unit of search</li>
<li>Prefix searches are efficient, contains searches are not</li>
<li>Modelling problems as prefix searches
<ul>
<li>Suffix matching - indexing reversed words</li>
<li>Contains matching - split words into n-grams</li>
<li>Decompound compound words</li>
<li>Geo coordinates - as geo hashes</li>
<li>Numerical and time ranges - store values trie-like</li>
<li>etc</li>
</ul>
</li>
</ul>
</li>
<li>Building indexes
<ul>
<li>Prioritize
<ul>
<li>search speed</li>
<li>index compactness</li>
<li>indexing speed</li>
<li>time to be visible</li>
</ul>
</li>
<li>Small index, faster search</li>
<li>Lucene indexes immutable</li>
<li>Deletions are only marked</li>
<li>Updates = delete + reinsert
<ul>
<li>Updating is costlier than inserting</li>
</ul>
</li>
<li>Index changes buffered in memory, eventually flushed (lucene) to disk = index segment</li>
</ul>
</li>
<li>Index segments
<ul>
<li>Advancements with lucene versions
<ul>
<li>Lucene <2.3 would make a segment for each doc, which were merged on flush</li>
<li>Nowadays, can make larger in-memory segments</li>
<li>Lucene 4 - one segment per thread - increased indexing performance, concurrent flushing</li>
<li>Flushing segments invalidates field and filter caches (which are per-segment)</li>
</ul>
</li>
</ul>
</li>
<li>Elasticsearch indexes
<ul>
<li>ES Index -> 1/more shards with 0/more replicas = lucene indexes -> 1/more index segments</li>
</ul>
</li>
</ul>
<hr />
<h2 id="elasticsearch-in-production">Elasticsearch in production</h2>
<ul>
<li><a href="https://www.elastic.co/blog/found-elasticsearch-in-production">https://www.elastic.co/blog/found-elasticsearch-in-production</a></li>
<li>Complicated system. Requires
<ul>
<li>network stability</li>
<li>Huge memory</li>
<li>assumptions that all users are trustworthy (are they?)</li>
</ul>
</li>
</ul>Chaitanya Pramodiam@chaitanyapramod.comhttps://chaitanyapramod.com/Notes from learning the basic working of ElasticsearchTime Management (slides)2018-01-08T10:00:00+05:302018-01-08T10:00:00+05:30https://chaitanyapramod.com/blog/time-management-slides<p>Practical and easily applicable tips on managing the scarcest resource in our life</p>
<p>(via http://softwareleadweekly.com/issues/266)</p>Chaitanya Pramodiam@chaitanyapramod.comhttps://chaitanyapramod.com/Practical and easily applicable tips on managing the scarcest resource in our lifePartitioning Complexity2017-12-26T00:30:00+05:302017-12-26T00:30:00+05:30https://chaitanyapramod.com/blog/partition-complexity<p>Kent Beck’s thoughts on managing complexity. Gem of an article.</p>
<p>Many useful tips for software development.</p>
<p>(via http://softwareleadweekly.com/issues/262)</p>Chaitanya Pramodiam@chaitanyapramod.comhttps://chaitanyapramod.com/Kent Beck’s thoughts on managing complexity. Gem of an article.Viral Loop & the Lean Startup2012-04-23T03:04:00+05:302012-04-23T03:04:00+05:30https://chaitanyapramod.com/blog/viral-loop-and-the-lean-startup<p>Disruption of internet service can make you do things you wouldn’t have imagined doing anytime soon. For me this weekend, it was reading books that have long been collecting dust on my desk. I read Viral Loop on Saturday and The Lean Startup on Sunday. These bullet points are just a way for me to recall what I learned from these books.</p>
<hr />
<h2 id="viral-loop-adam-penenberg"><a href="http://www.amazon.com/Viral-Loop-Facebook-Businesses-Themselves/dp/1401323499">Viral Loop</a> (Adam Penenberg)</h2>
<ul>
<li>Viral expansion loop
<ul>
<li>Viral loop</li>
<li>Viral network</li>
<li>Double viral loop</li>
</ul>
</li>
<li>Collective curation</li>
<li>Viral businesses
<ul>
<li>Tupperware and <a href="https://en.wikipedia.org/wiki/Ponzi_scheme">Ponzi-scheme</a> (Pyramid schemes), Netscape</li>
<li>Spreadable product</li>
<li>Virality Coefficient</li>
</ul>
</li>
<li>Characteristics of Viral loop businesses
<ul>
<li>Web-based</li>
<li>Free</li>
<li>Organizational technology</li>
<li>Simple concept</li>
<li>Built-in Virality</li>
<li>Extreme fast adoption (Hotmail, Facebook, Skype)</li>
<li>Virality Index (> 1.0)</li>
<li>Predictable growth rates</li>
<li>Network effects (Telephone, IMs, social networks)</li>
<li>Stackability (on another viral business)</li>
<li>Point of nondisplacement</li>
<li>Ultimate saturation</li>
</ul>
</li>
<li>Viral Marketing
<ul>
<li>Hotmail (remember <em>Get your free email at Hotmail</em> in email footer?)</li>
</ul>
</li>
<li>Viral Networks
<ul>
<li>eBay</li>
<li>PayPal stacked over eBay</li>
<li>MySpace</li>
<li>Flickr and YouTube stacked over MySpace</li>
</ul>
</li>
<li>Scaling issues of (almost) every viral product
<ul>
<li>eBay, Twitter</li>
</ul>
</li>
<li>Long tail vs heavy tail</li>
</ul>
<p>In the end, it just felt like reading stories of a couple of internet successes, but was an interesting read nevertheless.</p>
<hr />
<h2 id="the-lean-startup-eric-ries"><a href="http://theleanstartup.com/book">The Lean Startup</a> (Eric Ries)</h2>
<ul>
<li>Entrepreneurs are everywhere</li>
<li>Entrepreneurship is management</li>
<li>Incremental innovation vs disruptive innovation</li>
<li>Validated learning</li>
<li>Develop an MVP</li>
<li>Eliminate uncertainity - Test assumptions</li>
<li>Innovation accounting - vanity metrics and actionable metrics</li>
<li>Split testing (A/B testing)</li>
<li>Kanban principle:
<ul>
<li>Four stages of development of features:
<ul>
<li>Product backlog</li>
<li>Actively being built</li>
<li>Done (technically)</li>
<li>Being validated</li>
</ul>
</li>
</ul>
</li>
<li>Argument resolution through split test reports</li>
<li>Three A’s of metrics:
<ul>
<li>Actionable</li>
<li>Accessible</li>
<li>Auditable</li>
</ul>
</li>
<li>Pivot: Changing course with one foot anchored to the ground</li>
<li>Different pivots(and the <a href="https://www.votizen.com/">Votizen</a> story):
<ul>
<li>zoom-in pivot</li>
<li>customer segment pivot</li>
<li>Customer need pivot</li>
<li>platform pivot</li>
<li>plus more</li>
</ul>
</li>
<li>Pivot or Persevere</li>
<li>Single piece flow & effect of batch size
<ul>
<li>Large batch spiral death</li>
</ul>
</li>
<li>Countinuous innovation and continuous deployment</li>
<li>Build-measure-learn cycle and planning it backward</li>
<li>Controlled scaling (Gmail)</li>
<li>The five why’s</li>
<li>User story for every feature</li>
<li>Collect and organize feedback from various forums</li>
</ul>
<hr />
<p>You can find lots of common references between these two books. Overall, it has been an entertaining and meaningful journey. I recommend these books to anyone building a product s/he’s is expecting to take over the world. Now that these two books are off my <a href="https://www.goodreads.com/review/list/6917881?shelf=to-read">to-read list</a>, wondering what to read next… <a href="http://www.amazon.com/Toyota-Production-System-Beyond-Large-Scale/dp/0915299143">Toyota Production System</a> by Taiichi Ohno?</p>Chaitanya Pramodiam@chaitanyapramod.comhttps://chaitanyapramod.com/Notes on books Viral Loop and The Lean StartupFirst Post2012-02-12T12:30:00+05:302012-02-12T12:30:00+05:30https://chaitanyapramod.com/blog/first-post<p>Phew, just finished the basic setup of my brand-new blog-site. It took almost five hours to get here. Working with <a href="http://octopress.org">Octopress</a> was fun. Setting up a blog on commandline is way cooler than doing it the wordpress style. Of course, Octopress drew me to itself with its subtitle:</p>
<blockquote>
<p>A blogging framework for hackers.</p>
</blockquote>
<p>I noticed <a href="http://nimbupani.com/">Divya Manian</a> <a href="http://nimbupani.com/redesign-notes.html">move her blog to Octopress</a>. After looking up Octopress and what people feel about it (everyone seems to like it), I decided to try it myself.</p>
<p>After reading almost all of the <a href="http://octopress.org">Octopress</a> site, I cloned the <a href="http://github.com/imathis/octopress">Octopress repo</a>, setup a <a href="https://disqus.com">Disqus</a> account for the site and plugged in account into the config files. All commands are run through rake, which makes it as easy as:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">rake new_page[page_title] <span class="c"># create a new page </span>
rake new_post[post_title] <span class="c"># create a new post </span>
rake preview <span class="c"># fire up a local server and preview the site at localhost:4000 </span>
rake deploy <span class="c"># Make it live! :)</span></code></pre></figure>
<p>Just now realized that syntax highlighting breaks on Windows. Gotta find a fix for it soon. The Google Fonts were making the pages render slower, so I am thinking if they should be removed. The styles look good, but will spend some time on the CSS and fiddle around with it. Compass and SASS are new to me, more CSS frameworks to learn :(.</p>
<p>That’s it folks for now, will update with more changes I am planning to the site.</p>Chaitanya Pramodiam@chaitanyapramod.comhttps://chaitanyapramod.com/My journey setting up a Jekyll blog