tag:blogger.com,1999:blog-18985716949936595072024-02-02T21:08:37.244+05:30The Curious Techizen<strong><em>Note:-</em> This blog has moved <a href="http://kiranrao.in/blog">here</a>. Please visit the new blog for latest posts.</strong>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comBlogger21125tag:blogger.com,1999:blog-1898571694993659507.post-58775310343442649332015-09-29T13:18:00.001+05:302015-09-29T13:18:25.655+05:30Curious Techizen gets a new Home<div dir="ltr" style="text-align: left;" trbidi="on">
I am migrating this blog to its <a href="http://kiranrao.in/blog" target="_blank">own domain</a>. Furthermore, I am using <a href="https://jekyllrb.com/" target="_blank">jekyll </a>to turn this into a static site. You can view the source code for the blog <a href="https://github.com/curioustechizen/curioustechizen.github.io" target="_blank">here</a>.<br />
<br />
I have long wanted to do this. In fact I had written earlier about <a href="http://curioustechizen.blogspot.in/2013/03/shift-to-octopress-postponed.html" target="_blank">migrating to Octopress</a>, but had held back. I'm glad to be making the switch finally.<br />
<br />
I will retain the existing posts in this blog but will no longer publish new posts here. Please join me on the new blog for latest posts.</div>
Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-44758736455538493402014-02-09T12:26:00.001+05:302014-02-18T17:29:46.316+05:30Nested Fragments and the Backstack - Part 3<p>This is the third post in the series about Nested Fragments and the Back Stack in Android. Read the previous posts here:</p>
<ol>
<li><a href="http://curioustechizen.blogspot.com/2014/01/nested-fragments-and-back-stack.html">Part 1</a></li>
<li><a href="http://curioustechizen.blogspot.com/2014/02/nested-fragment-and-backstack-part-2.html">Part 2</a></li>
</ol>
<p>The first two posts have looked at the topic taking <code>ViewPager</code> as an example. I have also mentioned repeatedly that this is not the only use case for having to maintain the back-stack of nested fragments. One use case that I threw up often in comments was about <strong>Navigation Drawers</strong>. That is exactly what this post will look into.</p>
<hr>
<p><strong>EDIT: Some Google engineers, including the creators of the Android framework have expressed their reservations regarding this article. Read <a href="https://plus.google.com/100961288997176421259/posts/BLLi6srFtwT">this G+ thread</a> for more details. They point out that using an <code>Application</code> sub-class to save state is not a good idea, but also that saving <code>Fragment</code> instance state explicitly might in itself needs to be considered carefully. I hope to gather their thoughts and write a follow-up post in the coming weeks. Stay Tuned.</strong></p>
<hr>
<h3 id="re-cap">Re-cap</h3>
<p>Just to re-cap the conclusion from the previous article:</p>
<ul>
<li>Consider pro-actively saving your <code>Fragment</code> states in <code>onPause</code>, particularly is the <code>Fragment</code> happens to nest other fragments inside of it. </li>
<li>Do not rely solely on the system saving state for you in <code>onSaveInstanceState</code>.</li>
<li>Use <code>FragmentManager#saveFragmentInstanceState</code> to save the Fragment state including the back-stack of nested fragment transactions for you.</li>
<li>Do not hold on to the saved state any longer than necessary.</li>
</ul>
<h3 id="adapting-to-navigation-drawer">Adapting to Navigation Drawer</h3>
<p>If you take the <a href="https://github.com/curioustechizen/blog-nested-fragments-backstack/tree/master/nested-fragments-backstack-part2">source code for Part 2</a> of the series, and adapt it as-is to a Navigation Drawer example, you’ll find that things don’t quite work as you’d expect. In particular, you’ll find that <em>even though you have saved the state of the <code>ContainerFragment</code> in <code>onPause</code></em>, the next time you return to this fragment, its state is cleared. </p>
<p>Why is this? The alert reader might have spotted the reason.</p>
<p>In the case of the <code>ViewPager</code> example, we clear the saved fragment state in <code>onDestroy()</code>. This is because of the way ViewPager works (or rather, <code>FragmentPagerAdapter</code> or <code>FragmentStatePagerAdapter</code> works): When you navigate away from a tab, the Fragment’s <code>`onPause</code> is called but none of the other life-cycle methods are called. This means <code>onDestroy</code> is skipped and the Fragment is simply torn down. <code>onDestroy</code> is only called when the hosting <code>Activity</code> is destroyed.</p>
<pre style="" class="prettyprint prettyprinted"><code class="language-java"><span class="pln"> </span><span class="lit">@Override</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> onPause</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">super</span><span class="pun">.</span><span class="pln">onPause</span><span class="pun">();</span><span class="pln">
</span><span class="pun">((</span><span class="typ">NestedFragApp</span><span class="pun">)</span><span class="pln">getActivity</span><span class="pun">().</span><span class="pln">getApplication</span><span class="pun">()).</span><span class="pln">setFragmentSavedState</span><span class="pun">(</span><span class="pln">SAVED_STATE_KEY</span><span class="pun">,</span><span class="pln"> getFragmentManager</span><span class="pun">().</span><span class="pln">saveFragmentInstanceState</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">));</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="lit">@Override</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> onDestroy</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">super</span><span class="pun">.</span><span class="pln">onDestroy</span><span class="pun">();</span><span class="pln">
</span><span class="pun">((</span><span class="typ">NestedFragApp</span><span class="pun">)</span><span class="pln">getActivity</span><span class="pun">().</span><span class="pln">getApplication</span><span class="pun">()).</span><span class="pln">setFragmentSavedState</span><span class="pun">(</span><span class="pln">SAVED_STATE_KEY</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></code></pre>
<p>However, when you use a Navigation Drawer, the case is different. In this situation, there is no <code>PagerAdapter</code> to deal with. When you navigate from one item in the navigation drawer to another, the “old” Fragment undergoes the complete life-cycle - <code>onPause</code> all the way to <code>onDestroy</code> and <code>onDetach</code>. As a consequence, since you’re clearing the saved Fragment state in <code>onDestroy</code> of the <code>ContainerFragment</code>, <strong>you end up clearing the state that you had just saved in <code>onPause</code></strong>.</p>
<h3 id="solution">Solution?</h3>
<p>Well, the solution is rather simple - just don’t clear the state in <code>onDestroy</code> of the parent Fragment! In addition, there are a few other minor changes - like the way you set the initial state of the ContainerFragment (instead of retrieving the saved state in one of the life cycle methods of the Fragment, you use <code>setInitialSavedState</code> in the static creator method). The source code for this is available at the <a href="https://github.com/curioustechizen/blog-nested-fragments-backstack">github repo</a> for this series.</p>
<pre style="" class="prettyprint prettyprinted"><code class="language-java"><span class="pln"> </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="typ">ContainerFragment</span><span class="pln"> newInstance</span><span class="pun">(</span><span class="typ">SavedState</span><span class="pln"> savedState</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="typ">ContainerFragment</span><span class="pln"> frag </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ContainerFragment</span><span class="pun">();</span><span class="pln">
frag</span><span class="pun">.</span><span class="pln">setInitialSavedState</span><span class="pun">(</span><span class="pln">savedState</span><span class="pun">);</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> frag</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">...</span><span class="pln">
</span><span class="pun">...</span><span class="pln">
</span><span class="lit">@Override</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> onPause</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">super</span><span class="pun">.</span><span class="pln">onPause</span><span class="pun">();</span><span class="pln">
</span><span class="pun">((</span><span class="typ">NestedFragApp</span><span class="pun">)</span><span class="pln">getActivity</span><span class="pun">().</span><span class="pln">getApplication</span><span class="pun">()).</span><span class="pln">setFragmentSavedState</span><span class="pun">(</span><span class="pln">SAVED_STATE_KEY</span><span class="pun">,</span><span class="pln"> getFragmentManager</span><span class="pun">().</span><span class="pln">saveFragmentInstanceState</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">));</span><span class="pln">
</span><span class="pun">}</span></code></pre>
<p>Here’s a video showing this in action (Unfortunately the Android screenrecord tool doesn’t like it if you rotate the device during the recording, but I think the video demnostrates the point sufficiently):</p>
<iframe src="//www.youtube.com/embed/JEzerV4Ee_g" allowfullscreen="" height="315" width="420" frameborder="0"></iframe><div class="se-section-delimiter"></div>
<h3 id="forgetting-the-saved-state">Forgetting the saved state?</h3>
<p>The bullet points that we established in the previous post (re-capped at the beginning of this post) say that you should not hold on to the saved state any longer than necessary. However, we had to violate that rule in this solution because - well - it is pointless to save the state only to immediately clear it!</p>
<p>However, depending on your use case you might approach this in a different manner. For example, you might only clear the fragment saved state when the hosting <code>Activity</code> is destroyed. This is <em>not</em> demonstrated in the sample code on github but should be straightforward to implement.</p>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-54697628993177322542014-02-02T15:05:00.001+05:302014-02-18T17:29:58.627+05:30Nested Fragment and the BackStack - Part 2<p>This article is the second in this series about Nested Fragments and the Back Stack in Android. You can read Part 1 <a href="http://curioustechizen.blogspot.com/2014/01/nested-fragments-and-back-stack.html">here</a>. To get this post into context, take a look at the video embedded in the previous post, if nothing else.</p>
<p><strong>Edit: Later posts in this series at</strong></p>
<ol>
<li><a href="http://curioustechizen.blogspot.com/2014/02/nested-fragments-and-backstack-part-3.html">Part 3</a></li>
</ol>
<hr>
<p><strong>EDIT: Some Google engineers, including the creators of the Android framework have expressed their reservations regarding this article. Read <a href="https://plus.google.com/100961288997176421259/posts/BLLi6srFtwT">this G+ thread</a> for more details. They point out that using an <code>Application</code> sub-class to save state is not a good idea, but also that saving <code>Fragment</code> instance state explicitly might in itself needs to be considered carefully. I hope to gather their thoughts and write a follow-up post in the coming weeks. Stay Tuned.</strong></p>
<hr>
<p>At the risk of sounding repetitive, I’ll start off this post by once again stating the gist of the previous post:</p>
<blockquote>
<p>A Fragment’s <code>onSaveInstanceState</code> method is not guaranteed to be called when it is “removed”. The <code>Fragment</code> might simply be torn down. The only time its state might be saved is when the hosting <code>Activity</code> saves its state.</p>
</blockquote>
<p>We also saw how this could be a problem when you use nested fragments and a <code>FragmentManager</code> doesn’t save its backstack of fragment transactions. In this part, we’ll look at one possible solution to this problem.</p><div class="se-section-delimiter"></div>
<h3 id="save-state-in-onpause">Save state in onPause</h3>
<p>This is the obvious solution to the problem. The Android docs also state this time and again: it is a best practice to proactively save state. Also, since <code>onPause</code> is the only callback that is guaranteed to be called, it makes sense to save your instance state here.</p>
<p>Having said that, it is easy to save view states, scroll positions and even entire arbitrary objects in <code>onPause.</code> But, how does one save a back stack of fragment transactions?</p>
<p>Enter <a href="http://developer.android.com/reference/android/support/v4/app/Fragment.SavedState.html"><code>Fragment.SavedState</code></a>. You can ask the <code>FragmentManager</code> to save the state of a <code>Fragment</code> using <a href="http://developer.android.com/reference/android/support/v4/app/FragmentManager.html#saveFragmentInstanceState%28android.support.v4.app.Fragment%29"><code>saveFragmentInstanceState</code></a>. The back stack being managed by a Fragment’s nested <code>FragmentManager</code> is included in the state saved by this method.</p>
<h4 id="the-application-sub-class">The <code>Application</code> sub-class</h4>
<p>This post shows how you could use a sub-class of the <code>Application</code> class to save the state, but you might choose another mechanism to do so. The important thing is that the state has to be saved. We use a <code>Map</code> of strings as keys and the saved state as values in this example.</p>
<pre class="prettyprint"><code>public class NestedFragApp extends Application {
Map<String, Fragment.SavedState> savedStateMap;
@Override
public void onCreate() {
savedStateMap = new HashMap<String, Fragment.SavedState>();
super.onCreate();
}
public void setFragmentSavedState(String key, Fragment.SavedState state){
savedStateMap.put(key, state);
}
public Fragment.SavedState getFragmentSavedState(String key){
return savedStateMap.get(key);
}
}
</code></pre>
<h4 id="explicitly-saving-fragment-state">Explicitly saving Fragment state</h4>
<p>Then, you save the state of the container fragment when it pauses as follows:</p>
<pre class="prettyprint"><code>@Override
public void onPause() {
super.onPause();
((NestedFragApp) getActivity().getApplication()).setFragmentSavedState(
SAVED_STATE_KEY, getFragmentManager().saveFragmentInstanceState(this));
}
</code></pre>
<h4 id="initializing-the-fragment-transaction">Initializing the fragment transaction</h4>
<p>Finally, remember to check whether there is a saved state for this fragment before “initializing” the fragment transaction:</p>
<pre class="prettyprint"><code>SavedState fragmentSavedState = ((NestedFragApp)getActivity().getApplication())
.getFragmentSavedState(SAVED_STATE_KEY);
if(fragmentSavedState == null){
if (savedInstanceState == null) {
getChildFragmentManager().beginTransaction().replace(R.id.nested_fragment_container,
NestedFragmentOne.newInstance()).commit();
} else {
// use savedInstanceState here to restore state saved in onSaveInstance
}
}
</code></pre>
<p>Note that there are two “saved states” here:</p>
<ol>
<li>The instance state saved in <code>onSaveInstanceState</code>, which is provided to you by the system via <code>savedInstanceState</code>.</li>
<li>The state you explicitly saved in <code>onPause</code>, which you retrieve from the <code>Application</code> object as <code>fragmentSavedState</code>.</li>
</ol>
<p>The flow you follow for initializing the fragment is as follows:</p>
<ul>
<li>You first check to see if you had previously explicitly saved state. If true, then you don’t need to do anything.</li>
<li>If not, then you proceed to check if the system had saved state for you. If true, then you use the <code>savedInstanceState</code> to restore system-saved state.</li>
<li>Only if neither is true, then you initiate the fragment transaction.</li>
</ul>
<h4 id="letting-go-of-the-saved-state">Letting go of the saved state</h4>
<p>One thing you need to be careful of is to not hold on to the saved fragment state any longer than necessary. For example, when the <strong>container <code>Fragment</code></strong> is destroyed, you want to invalidate the back-stack associated with it as well. This sounds obvious but I overlooked it and ended up with strange behaviors.</p>
<p>The best way I found was to “forget” the saved state of a container fragment in its <code>onDestroy</code>:</p>
<pre class="prettyprint"><code>@Override
public void onDestroy() {
super.onDestroy();
((NestedFragApp) getActivity().getApplication()).setFragmentSavedState(
SAVED_STATE_KEY, null);
}
</code></pre>
<p>With all these steps in place, the app now behaves as one would expect it to. Your position within a back-stack, even within a nested fragment, is remembered even when you navigate away and return to the top level fragment.</p>
<p>Here’s a video showing how the app now behaves:</p>
<iframe src="//www.youtube.com/embed/7RpzkXGJqNo" allowfullscreen="" frameborder="0" height="315" width="420"></iframe>
<p>The source code for the entire series is at <a href="https://github.com/curioustechizen/blog-nested-fragments-backstack">github</a>.</p><div class="se-section-delimiter"></div>
<h3 id="conclusion">Conclusion</h3>
<ul>
<li>Consider pro-actively saving your <code>Fragment</code> states in <code>onPause</code>, particularly is the <code>Fragment</code> happens to nest other fragments inside of it. </li>
<li>Do not rely solely on the system saving state for you in <code>onSaveInstanceState</code>.</li>
<li>Use <code>FragmentManager#saveFragmentInstanceState</code> to save the Fragment state including the back-stack of nested fragment transactions for you.</li>
<li>Do not hold on to the saved state any longer than necessary.</li>
</ul>
<p>This article looked at ActionBar tabs with a ViewPager, but this concept applies to other situations where one would use nested Fragments (Navigation Drawers for example).</p>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-79119245255680880092014-01-25T23:09:00.001+05:302014-02-09T19:48:46.557+05:30Nested Fragments and the Back Stack<p>This article is not about the back stack of <em>activities</em> that Android maintains for every task. That stuff has been written about adequately elsewhere. This post is about the back stack of <em>fragment transactions</em> maintained by the <a href="http://developer.android.com/reference/android/support/v4/app/FragmentManager.html"><code>FragmentManager</code></a> and how they relate to nested fragments.</p>
<p><strong>Edit: Other posts in this series at</strong></p>
<ol>
<li><a href="http://curioustechizen.blogspot.com/2014/02/nested-fragment-and-backstack-part-2.html">Part 2</a></li>
<li><a href="http://curioustechizen.blogspot.com/2014/02/nested-fragments-and-backstack-part-3.html">Part 3</a></li>
</ol>
<p><strong>Heads-up:</strong> If you are using nested fragments, you need to use the support library, even if your app only targets API level 14 and above. This is because nested fragment support was <a href="http://developer.android.com/about/versions/android-4.2.html#NestedFragments">added in API 17</a>, and the feature was back-ported to the support library (revision 11 and later).</p>
<h3 id="tldr">TL;DR</h3>
<p>The gist of this post can be stated as follows:</p>
<blockquote>
<p>There are many situations where a fragment may be mostly torn down (such as when placed on the back stack with no UI showing), but its <strong>state will not be saved until its owning activity actually needs to save its state</strong>.</p>
</blockquote>
<p>This is from the <a href="http://developer.android.com/reference/android/support/v4/app/Fragment.html#onSaveInstanceState%28android.os.Bundle%29">docs</a> (emphasis mine). Overlooking this can lead to bugs especially when you use nested fragments since the back stack of a child fragment manager could be reset when you least expect it. Remember - if the state of a <code>Fragment</code> is not saved, then by definition, the back stack of fragment transactions managed by that fragment’s child <code>FragmentManager</code> is not saved either.</p>
<h3 id="the-problem">The Problem</h3>
<p>With the advent of fragments, more so nested fragments, the general advice one gets from the developer community is this:</p>
<blockquote>
<p>Fragmentize all the everythings!</p>
</blockquote>
<p>And with good reason too. Consider the following:</p>
<ul>
<li>If you use ActionBar tabs, the content of each tab is implemented as a <code>Fragment</code>.</li>
<li>Each “page” in a <code>ViewPager</code> is often implemented as a <code>Fragment</code>.</li>
<li>In navigation drawers, the “content” of each navigation item is expected to be a <code>Fragment</code>.</li>
</ul>
<p>What this translates to is that what would once be implemented as an <code>Activity</code> now needs to be implemented as a <code>Fragment</code>. This also means that a <em>flow within that <code>Activity</code></em>, that might have been implemented using <code>Fragment</code>s, now needs to be implemented using <strong>nested <code>Fragment</code>s</strong>. Note that by “flow” I simply mean a sequence of screens to establish a particular task.</p>
<p>Now here’s the thing with flows: If a user “goes away” from a flow and later returns to it, it is expected that the user continues from the screen where they left off. Translated into <code>Fragment</code> terminology, this means that if a user navigates away and returns to a flow that is implemented using <code>Fragment</code>s, its is expected that the user’s position in the backstack of fragment transactions is retained. However, this isn’t always the case.</p>
<p>Here is a video demonstrating the problem:</p>
<iframe src="//www.youtube.com/embed/3gRq3hG9tS4" allowfullscreen="" frameborder="0" height="315" width="420"></iframe>
<p>The video shows an <code>Activity</code> with three tabs. It is a modified version of an <code>Activity</code> created using the “New Activity” wizard in ADT or Android Studio and specifying “Fixed Tabs + Swipe” navigation. The modification is as follows:</p>
<ul>
<li>The content of the first tab has been modified to make it a “Container” <code>Fragment</code> that in turn contains two nested fragments.</li>
<li>When the container fragment is first created, it shows a nested fragment asking you to enter your name.</li>
<li>On entering the name and Clicking “Next”, you are presented with another nested fragment asking you to enter your GitHub username.</li>
<li>The other two tabs are just simple <code>Fragment</code>s - no nesting business there.</li>
</ul>
<p>Now, notice what happens when I follow this sequence:</p>
<ol>
<li>Enter name, press Next. Then, enter a github username.</li>
<li>Navigate to the tab titled “Section 2” and then back to “Section 1”.</li>
<li>Navigate to the tab titled “Section 3” and then back to “Section 1”.</li>
</ol>
<p>Uh! In step 3 above, the back stack was nuked. But hey, it didn’t happen in Step 2. Why so?</p>
<h3 id="explanation">Explanation</h3>
<p>This example uses a <code>ViewPager</code>. By default, a <code>ViewPager</code> has an “off screen limit” of 1. This means that in addition to the page being displayed, one adjacent page in each direction is kept in memory. So, when you navigate to “Section 2”, everything in “Section 1” is still intact in memory.</p>
<p>When you navigate to “Section 3”, the page corresponding to “Section 1” is torn down. More importantly, since at this point the <code>Activity</code> instance state is not being saved, the <code>Fragment</code> state isn’t saved either. This ties in with what we saw in the “TL;DR” section above. As a result, when you navigate back to “Section 1”, the nested fragment back stack is reset.</p>
<h3 id="rotation-task-switching">Rotation? Task Switching?</h3>
<p>Try following this sequence of steps:</p>
<ol>
<li>Enter name, press Next. Then, enter a github username.</li>
<li>Rotate the device; or switch to another app and return back to this app</li>
</ol>
<p>Now you’ll see that the back stack is retained. This is because when you rotate the device or switch to another task, the Activity saves its instance state. As a consequence the container fragment does too.</p>
<h3 id="conclusion">Conclusion</h3>
<p>Re-iterating what we started off this post with, <strong>keep in mind when you are using nested fragments that a <code>Fragment</code> is guaranteed to save state only when the containing <code>Activity</code> saves its instance state. At other times, the <code>Fragment</code> might simply be torn down</strong>.</p>
<p>The code for a sample app illustrating the problem is available <a href="https://github.com/curioustechizen/blog-nested-fragments-backstack">at github</a>. The next part of this series will explore ways to overcome this problem.</p>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-89035868242839482852013-06-08T23:33:00.001+05:302013-06-08T23:33:26.116+05:30Android ListViews: "Hybrid" Choice Behavior<p>The goal of this post is to use a <code>ListView</code> in a master/detail configuration where <em>both</em> of the following are possible:</p>
<ol>
<li>Touch a single item to <strong>open</strong> it.</li>
<li>Long-tap multiple items to <strong>choose</strong> them and perform a common action on them.</li>
</ol>
<p>Note that we wish both these to be possible simultaneously, i.e., even as one item is opened, we wish to allow multiple items (possibly including the item that is opened) to be chosen.</p>
<p>This behavior (with some minor variations) is seen in apps like GMail, Google Play Store and the Google I/O 2013 app.</p>
<p>The following screenshot shows what we want to achieve. It shows one opened item (Item 5) and two chosen items (Item 3 and Item 8)</p>
<p><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGBu0bcx1E2gYW2wtP3Wn6bn46iVYIti9jyiyqOHEEXJsDYiPt-f8jzwSkrhbrTX1qT4iZUUPCSxWNW62JiFFwTSUaxLVzQpBRfX-UtVHn1Ctc3N9rYzt1quc3R2vUz0J1ytNS6A2yrJs/s512/target_ui.png" alt="This is what we want to achieve" title="target_ui.png"></p>
<h3 id="a-note-on-the-terminology">A note on the terminology</h3>
<p>Just to avoid confusion, let's sort of formalize the terminology related to the states an item in the list can be in.</p>
<blockquote>
<p>An item is <strong>opened</strong> when the user is viewing the details about that item. In other words, the details of that item are being displayed in the <code>DetailFragment</code>. In dual-pane mode, there needs to be some visual indication in the <code>ListView</code> to let the user know which one of the items is currently opened.</p>
<p>When an item is <strong>chosen</strong>, the Contextual Action Bar appears and the user can perform some action on the item. When multiple items are chosen, only the contextual actions that apply to all of them are to be presented. There needs to be some visual indication in the <code>ListView</code> to let the user know which of the items are currently chosen. Needless to say, this indication needs to differ from the that used to indicate the opened item.</p>
</blockquote>
<h3 id="implementation">Implementation</h3>
<p>You might notice that one can achieve the opened behavior using <code>ListView</code>'s <code>CHOICE_MODE_SINGLE</code> and the chosen behavior using <code>CHOICE_MODE_MULTIPLE_MODAL</code>. However, it is while trying to combine them that things begin to get challenging, particularly in dual-pane mode. You get either one or the other, but never both. For example, if you use <code>CHOICE_MODE_MULTIPLE_MODAL</code>, then you lose the ability to visually indicate the currently opened item.</p>
<p>The solution I ended up with was to not rely on the <code>CHOICE_MODE_MULTIPLE_MODAL</code>, but rather simulate it myself. The high level steps are as follows:</p>
<ol>
<li>Create a custom <code>ListAdapter</code> that keeps track of the currently opened item and the currently chosen items</li>
<li>In the <code>getView()</code> (or equivalent) method of your custom <code>ListAdapter</code>, examine the item at the supplied <code>position</code>. If it is the currently opened item, set its visual properties to indicate this. Ditto if it is one of the chosen items.</li>
<li>Listen for clicks and long clicks on your <code>ListView</code> and update the adapter defined in step 1 accordingly- i.e., in your <code>OnItemClickListener</code> implementation, set the opened item and in <code>OnItemLongClickListener</code>, update the list of chosen items.</li>
<li><code>OnItemLongClickListener</code> is also where you need to start the action mode (<code>getListView().startActionMode()</code>) if it isn't started already.</li>
</ol>
<h3 id="hybridchoiceadapter">HybridChoiceAdapter</h3>
<p>Here are relevant portions of the code showing how the Adapter should be customized. This code is sparsely commented since I hope that it is self explanatory. Please look at the end of this post for the link to the complete github project.</p>
<pre class="prettyprint prettyprinted" style=""><code><span class="pln"> </span><span class="com">/* Keep track of currently opened item and chosen items */</span><span class="pln">
</span><span class="kwd">private</span><span class="pln"> </span><span class="typ">Set</span><span class="pun"><</span><span class="typ">Integer</span><span class="pun">></span><span class="pln"> chosenItems </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">HashSet</span><span class="pun"><</span><span class="typ">Integer</span><span class="pun">>();</span><span class="pln">
</span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> openedItem </span><span class="pun">=</span><span class="pln"> </span><span class="pun">-</span><span class="lit">1</span><span class="pun">;</span><span class="pln">
</span><span class="com">//...snip...</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> setItemChosen</span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> position</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">boolean</span><span class="pln"> chosen</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">chosen </span><span class="pun">&&</span><span class="pln"> isItemChosen</span><span class="pun">(</span><span class="pln">position</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
chosenItems</span><span class="pun">.</span><span class="pln">remove</span><span class="pun">(</span><span class="pln">position</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">chosen </span><span class="pun">&&</span><span class="pln"> </span><span class="pun">!</span><span class="pln">isItemChosen</span><span class="pun">(</span><span class="pln">position</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
chosenItems</span><span class="pun">.</span><span class="pln">add</span><span class="pun">(</span><span class="pln">position</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">boolean</span><span class="pln"> isItemChosen</span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> position</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> chosenItems</span><span class="pun">.</span><span class="pln">contains</span><span class="pun">(</span><span class="pln">position</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="typ">Set</span><span class="pun"><</span><span class="typ">Integer</span><span class="pun">></span><span class="pln"> getChosenItems</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> chosenItems</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> setOpenedItem</span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> position</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">openedItem </span><span class="pun">=</span><span class="pln"> position</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> getOpenedItem</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">openedItem</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">boolean</span><span class="pln"> isItemOpened</span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> position</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">openedItem </span><span class="pun">==</span><span class="pln"> position</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> clearChoices</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
chosenItems</span><span class="pun">.</span><span class="pln">clear</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> toggleItem</span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> position</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">isItemChosen</span><span class="pun">(</span><span class="pln">position</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
chosenItems</span><span class="pun">.</span><span class="pln">remove</span><span class="pun">(</span><span class="pln">position</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
chosenItems</span><span class="pun">.</span><span class="pln">add</span><span class="pun">(</span><span class="pln">position</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> getChosenItemsCount</span><span class="pun">(){</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">chosenItems</span><span class="pun">.</span><span class="pln">size</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></code></pre>
<h3 id="the-getview-method">The <code>getView()</code> method</h3>
<p>At this point, we have set up the <code>Adapter</code> to keep track of the currently opened item and the chosen items too. We have also exposed methods to manipulate these values. Now, lets look at the code that updates the UI. It is rather simple - all we need to do is, set the background of the row view depending on the opened and chosen states of the current item. Note that an item can be both opened and chosen.</p>
<pre class="prettyprint prettyprinted" style=""><code><span class="pln"> </span><span class="lit">@Override</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">final</span><span class="pln"> </span><span class="typ">View</span><span class="pln"> getView</span><span class="pun">(</span><span class="kwd">final</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> position</span><span class="pun">,</span><span class="pln"> </span><span class="typ">View</span><span class="pln"> convertView</span><span class="pun">,</span><span class="pln">
</span><span class="typ">ViewGroup</span><span class="pln"> parent</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="typ">View</span><span class="pln"> v </span><span class="pun">=</span><span class="pln"> convertView</span><span class="pun">;</span><span class="pln">
</span><span class="com">/*Normal procedure to inflate the row layout and set its properties goes here*/</span><span class="pln">
v</span><span class="pun">.</span><span class="pln">setBackgroundResource</span><span class="pun">(</span><span class="lit">0</span><span class="pun">);</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">isItemOpened</span><span class="pun">(</span><span class="pln">position</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
setViewAsOpened</span><span class="pun">(</span><span class="pln">v</span><span class="pun">);</span><span class="pln"> </span><span class="com">//This method sets the appropriate background resource or drawable</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">isItemChosen</span><span class="pun">(</span><span class="pln">position</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
setViewAsChosen</span><span class="pun">(</span><span class="pln">v</span><span class="pun">);</span><span class="com">//This method sets the appropriate background resource or drawable</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> v</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></code></pre>
<h3 id="listening-for-clicks-on-the-listview">Listening for clicks on the <code>ListView</code></h3>
<p>In your <code>Activity</code> or <code>Fragment</code>, we listen for both clicks and long clicks and update the adapter accordingly. Again, only the relevant portions of the code are presented here - the full project is shared on github (linked at the end of this post). Here we use a <code>ListAdapter</code> that also implements <code>OnItemLongClickListener</code>.</p>
<pre class="prettyprint prettyprinted" style=""><code><span class="pln"> </span><span class="lit">@Override</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> onListItemClick</span><span class="pun">(</span><span class="typ">ListView</span><span class="pln"> listView</span><span class="pun">,</span><span class="pln"> </span><span class="typ">View</span><span class="pln"> view</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> position</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">long</span><span class="pln"> id</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">super</span><span class="pun">.</span><span class="pln">onListItemClick</span><span class="pun">(</span><span class="pln">listView</span><span class="pun">,</span><span class="pln"> view</span><span class="pun">,</span><span class="pln"> position</span><span class="pun">,</span><span class="pln"> id</span><span class="pun">);</span><span class="pln">
</span><span class="com">//When an item is clicked, set it as the opened item</span><span class="pln">
mAdapter</span><span class="pun">.</span><span class="pln">setOpenedItem</span><span class="pun">(</span><span class="pln">position</span><span class="pun">);</span><span class="pln">
</span><span class="com">//At this point, clear all choices</span><span class="pln">
mAdapter</span><span class="pun">.</span><span class="pln">clearChoices</span><span class="pun">();</span><span class="pln">
</span><span class="kwd">if</span><span class="pun">(</span><span class="pln">mActionMode </span><span class="pun">!=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">){</span><span class="pln">
mActionMode</span><span class="pun">.</span><span class="pln">finish</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
mAdapter</span><span class="pun">.</span><span class="pln">notifyDataSetChanged</span><span class="pun">();</span><span class="pln">
</span><span class="com">// code to show the details fragment goes here</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="lit">@Override</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">boolean</span><span class="pln"> onItemLongClick</span><span class="pun">(</span><span class="typ">AdapterView</span><span class="pun"><?></span><span class="pln"> parent</span><span class="pun">,</span><span class="pln"> </span><span class="typ">View</span><span class="pln"> view</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> position</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">long</span><span class="pln"> id</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="com">//When an item is long clicked, toggle its chosen state</span><span class="pln">
</span><span class="com">//Also update the CAB title to reflect the change in number of chosen items</span><span class="pln">
mAdapter</span><span class="pun">.</span><span class="pln">toggleItem</span><span class="pun">(</span><span class="pln">position</span><span class="pun">);</span><span class="pln">
updateActionMode</span><span class="pun">();</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> updateActionMode</span><span class="pun">(){</span><span class="pln">
</span><span class="kwd">if</span><span class="pun">(</span><span class="pln">mActionMode </span><span class="pun">==</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">){</span><span class="pln">
mActionMode </span><span class="pun">=</span><span class="pln"> getListView</span><span class="pun">().</span><span class="pln">startActionMode</span><span class="pun">(</span><span class="pln">actionModeCallback</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
mActionMode</span><span class="pun">.</span><span class="pln">setTitle</span><span class="pun">(</span><span class="typ">String</span><span class="pun">.</span><span class="pln">format</span><span class="pun">(</span><span class="str">"%d chosen"</span><span class="pun">,</span><span class="pln"> mAdapter</span><span class="pun">.</span><span class="pln">getChosenItems</span><span class="pun">().</span><span class="pln">size</span><span class="pun">()));</span><span class="pln">
mAdapter</span><span class="pun">.</span><span class="pln">notifyDataSetChanged</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></code></pre>
<p>The previous code snippet also includes step 4 from our high level overview. If the CAB is not already shown, we show it when an item is long clicked.</p>
<p>That mostly covers what we need to do to achieve our goal. There are a few other things that need to be taken care of (for example, clearing the choices whenever the CAB is dismissed - as a result of a contextual action being performed, or otherwise). You can examine the entire code in detail at the github repository.</p>
<h3 id="variations">Variations</h3>
<p>There are subtle variations of what action the user has to take to choose an item. For example,</p>
<ul>
<li>The old GMail app (v4.3) displayed check boxes for each row. So you could choose an item either by long-pressing it, or by tapping the check box.</li>
<li>In the new GMail app and the Google I/O 2013 app, when no item is chosen, you long-press an item to choose it. After that, <strong>even single clicking on other items chooses them</strong>. This is different from our implementation where a single-tap always opens an item.</li>
</ul>
<p>You will need to modify the code for the click listeners if you want to go with one of these variations. The <code>ListAdapter</code> code itself should remain the same.</p>
<h3 id="turning-this-into-a-library">Turning this into a library?</h3>
<p>Well, I gave this a thought too. Exposing the custom <code>Adapter</code> as a library is the easy part. What I couldn't decide upon is how to include the <code>ListView</code> listeners in a library. Developers might wish to extend <code>ListActivity</code> or <code>ListFragment</code> or simply include a <code>ListView</code> in their layouts. Catering to so many requirements is a tough ask (unless I want to provide custom base versions of all these classes ... plus their <code>Sherlock</code> counterparts!)</p>
<p>If anyone has any ideas on how this could be library-ized, please do drop a comment.</p>
<h3 id="github-repositroy">GitHub repositroy</h3>
<p>The complete source code for this article is available as a sample project on GitHub <a href="https://github.com/curioustechizen/android-hybridchoice">here</a>.</p>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-76120992228975688202013-03-09T11:04:00.000+05:302013-03-09T11:04:02.538+05:30Shift to Octopress Postponed<div dir="ltr" style="text-align: left;" trbidi="on">
<p>For some time now, I have been toying with the idea of migrating this blog to <a href="http://octopress.org/">octopress</a>. I'm already using Markdown to compose my posts, so this is a logical step for me. Also, the idea of a static site that I can take with me wherever I choose to host it appeals to me. Finally, there's the geek factor what with git-based publish workflows and SCSS/liquid customizations and what not. I had even chosen a theme - <a href="http://panks.me/blog/2013/01/new-octopress-theme-fabric/">Fabric</a> - to use as my base theme.</p>
<p>However, it looks like I'm going to have to postpone migration to Octopress. Here are some of the reasons:</p>
<h3>Redirection</h3>
<p>I'm not sure how to deal with links to my existing posts. I have seen examples of how to do this if you are self-hosting your current blog, or if you are using your own domain name. Neither of these apply to me - my current blog is hosted on blogger, with a <code>.blogspot</code> domain. </p>
<h3>Comments</h3>
<p>I'm already using Disqus for comments on my blog. I gather that it should be possible to migrate Disqus comments even if your domain changes. I just haven't figured out how.</p>
<h3>Importing</h3>
<p>I tried using some custom Ruby scripts to import my existing posts into Octopress. While it works, there are two problems I need to deal with:</p>
<ul>
<li>
<p><strong>Syntax Highlighting:</strong> In blogger, syntax highlighting is done dynamically by Javascript (I use google's prettify.js). While this can be used with static site generators, it is best to stick to introducing syntax highlighting at the <em>post generation time</em>. This is all fine for new posts, but for posts that I import from blogger, this needs additional tweaking. Basically the imported sources are just HTML with some YAML front-matter. I will need to convert it to markdown, add the syntax highlighting annotations and then generate the posts from it.</p>
</li>
<li>
<p><strong>Permalinks:</strong> This goes back to the redirection I already mentioned. I also need to customize the permalinks of imported posts to make sure they play nice with redirection. Again, this is not a problem for newer posts. Only the imported posts need to be tweaked.</p>
</li>
</ul>
<h3>Looking Forward</h3>
<p>I'm not saying that any of the above impossible (or even very difficult) to achieve. It is just that some amount of experimentation is involved. I feel that it would take up more time than I am willing to invest at this point to get things up and running.</p>
<p>This is not to say that I have shelved the idea of shifting to a static site generator altogether. On the contrary. This shift is surely happening. It has just been deferred.</p>
<p>The easiest approach would be to maintain my current blog at http://curioustechizen.blogspot.com/ and start the octopress blog afresh. No imports from blogger. No redirection. Only new posts at the new blog. This approach is not without its downsides though.</p>
<p>So, in a nutshell:</p>
<blockquote>
<p>I will surely be migrating to a static site generator like octopress in the near future. But for now, I'm sticking with blogger.</p>
</blockquote>
<br /></div>
Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-34913712692120488862013-02-18T13:30:00.000+05:302015-06-25T16:21:52.819+05:30Android Constants: Preference Keys, Actions, Extras and more<p>The content of this post may seem ... well .. trivial at first, but I have tripped over these so many times that I decided to write it up - at least to keep me reminded of it, if not for any other reason!</p>
<p>If you have written anything more than a HelloWorld app in Android, chances are you have had to work with a plethora of program elements that are represented as <code>String</code>s. Consider this sampling:</p>
<ul>
<li>Keys for <code>SharedPreferences</code> are <code>String</code>s</li>
<li>Keys for <code>Bundle</code>s are <code>String</code>s</li>
<li><code>Intent</code> extras are <code>Bundle</code>s, and hence, if you want to include any extras or retrieve them from <code>Intent</code>s, you use their <code>String</code> keys to work with them. Ditto with <code>Fragment</code> arguments</li>
<li><code>Intent</code> and <code>IntentFilter</code> actions (and categories) are <code>String</code>s themselves</li>
<li>. . .</li>
</ul>
<p>I used to deal with these the lazy way: Declare the keys as <code>public static</code> where they are first used (or where they "belong" logically) and refer to them from wherever they are needed in the code. Examples of the class that is the logical owner might be:</p>
<ul>
<li>The class that broadcasts an <code>Intent</code></li>
<li>The class that creates or sends a non-broadcast <code>Intent</code> (this might be an <code>Activity</code> or <code>Service</code> for example)</li>
<li>The class that creates a <code>SharedPreference</code> for editing</li>
</ul>
<p>However, I quickly found out that often it is not possible to cleanly define these keys as belonging to a particular class. Further, since you might end up with a handful of extras, qualifying the class name becomes tedious - more so since it is likely that Activities or Services can have quite long names. How readable is this snippet?</p>
<p><a id="basic-example"></a></p>
<pre class="prettyprint"><code>if(AbstractBaseLiveModeActivity.ACTION_LIVE_UPDATE.equals(intent.getAction())){
Bundle extras = intent.getExtras();
if(extras.containsKey(AbstractBaseLiveModeActivity.EXTRA_LIVE_UPDATE_TIMESTAMP)){
long timestamp = extras.getLong(AbstractBaseLiveModeActivity.EXTRA_LIVE_UPDATE_TIMESTAMP);
// Do something with timestamp here
}
}
</code></pre>
<h3>Constants Almighty</h3>
<p>One common solution to this problem is to put everything into one "God" object called <code>Constants</code> or whatever, and prefix the constant names with <code>EXTRA_</code>, <code>ACTION_</code> or other such descriptive characters to keep them distinct.</p>
<pre class="prettyprint"><code>public class Constants{
private Constants(){}
public static final String ACTION_LIVE_UPDATE = "com.myawesomeapp.action.LIVE_UPDATE";
// ...
public static final String EXTRA_LIVE_UPDATE_TIMESTAMP = "com.myawesomeapp.extra.LIVE_UPDATE_TIMESTAMP";
// ...
}
</code></pre>
<p>Now, we've solved the readability problem since we just qualify the constant names with <code>Constant.</code> So, all's well, right?</p>
<p><a id="disadvantages"></a>
<strong>Wrong!</strong></p>
<p>The problem with this approach is as the number of extras, actions and preference keys increases, the <code>Constants</code> class quickly becomes unmanageable. Also, having to use the <code>ACTION_</code> and <code>EXTRA_</code> prefixes hinders usability with some IDE's. For example, with Eclipse, even if you know that you want <code>EXTRA_LIVE_UPDATE_TIMESTAMP</code>, you are forced to type the first six characters without which the code assist will not be able to filter only the extras.</p>
<p>Try using Eclipse to find a particular action or extra from the <code>Intent</code> class if you want to see a real-world example of what I mean.<br>
</p>
<p><a id="split-constant-files"></a></p>
<h3>Split it up into distinct constant files</h3>
<p>Here's what I do to keep my code free of such stutter. I simply split up the "God" <code>Constants</code> class into several smaller, easier-to-manage constants classes. Like so:</p>
<pre class="prettyprint"><code>public class Extras{
private Extras(){}
private static String createExtra(String suffix){
return Constants.NAMESPACE_PREFIX + ".extra."+suffix; //NAMESPACE_PREFIX could be "com.myawesomeapp"
}
public static final String LIVE_UPDATE_TIMESTAMP = createExtra("LIVE_UPDATE_TIMESTAMP");
public static final String LIVE_UPDATE_VALUE = createExtra("LIVE_UPDATE_VALUE");
public static final String FRIEND_ID = createExtra("FRIEND_ID");
// ...
}
public class Broadcasts{
private Broadcasts(){}
private static String createBroadcast(String suffix){
return Constants.NAMESPACE_PREFIX + ".broadcast."+suffix; //NAMESPACE_PREFIX could be "com.myawesomeapp"
}
public static final String LIVE_UPDATE = createBroadcast("LIVE_UPDATE");
public static final String FRIEND_OFFLINE = createBroadcast("FRIEND_OFFLINE");
// ...
}
public class Actions{
private Actions(){}
private static String createAction(String suffix){
return Constants.NAMESPACE_PREFIX + ".action."+suffix; //NAMESPACE_PREFIX could be "com.myawesomeapp"
}
public static final String JOIN_CHAT = createAction("JOIN_CHAT");
// ...
}
</code></pre>
<p>You could create classes for Categories, Preference Keys and so on. Note that I differentiate between Broadcasts and Actions because although they are both Intents, they are logically very different. Now, <a href="#basic-example">this code snippet</a> changes to:</p>
<pre class="prettyprint"><code>if(Broadcasts.LIVE_UPDATE.equals(intent.getAction())){
Bundle extras = intent.getExtras();
if(extras.containsKey(Extras.LIVE_UPDATE_TIMESTAMP)){
long timestamp = extras.getLong(Extras.LIVE_UPDATE_TIMESTAMP);
// Do something with timestamp here
}
}
</code></pre>
<p>Which code snippet would your rather see, especially six months from now when you have to fix a bug? Also note that we've made it far more easy to find the exact action or extra that we want using our IDEs.<br>
</p>
<h3>Wait, what about constants in XMLs?</h3>
<p>Glad you asked. In android, many of these constants are used not only in Java code, but also from XML files.</p>
<ul>
<li>Preference keys can be referenced in <a href="http://developer.android.com/guide/topics/ui/settings.html#DefiningPrefs">preferences XML</a> files via the <code><PreferenceScreen></code> element.</li>
<li>Intents can be declared in <code>AndroidManifest.xml</code>. This means, the <code>Intent</code> action and categories can be referenced from the manifest.</li>
<li><code>BroadcastReceiver</code>s can be declared in <code>AndroidManifest.xml</code>. The <code><intent-filter></code> action and categories are referenced here.</li>
<li>. . .</li>
</ul>
<p>This presents a problem since we end up duplicating the constants here. We cannot use our <code>Broadcasts.LIVE_UPDATE</code> constant in XML, so we tend to repeat the constant value:</p>
<pre class="prettyprint"><code><intent-filter>
<action android:name="com.myawesomeapp.broadcast.LIVE_UPDATE"/>
</intent-filter>
</code></pre>
<p>This is not good. Any change to any constant involves updating it at multiple places. What's more, these issues are not caught at compile time and can be hard to debug.<br>
</p>
<h3>Using String resources to avoid duplication</h3>
<p>One way to avoid constant literal duplication issue explained in the previous section is to use <a href="http://developer.android.com/guide/topics/resources/string-resource.html">string resources</a>. You are already using string resources for a variety of strings in your Android app. (Wait, you aren't? I strongly suggest you start doing so right now). All you need to do is add the constants as additional string resources. </p>
<p>To keep things clean, you could keep these constants in their own file under <code>values/</code> folder - for example <code>constants.xml</code>. In there, you could add</p>
<pre class="prettyprint"><code><resources>
<!-- Broadcast Actions -->
<string name="broadcast_live_update">com.myawesomeapp.broadcast.LIVE_UPDATE</string>
<string name="broadcast_friend_offline">com.myawesomeapp.broadcast.FRIEND_OFFLINE</string>
<!-- Intent Extras -->
<string name="extra_live_update_timestamp">com.myawesomeapp.extra.LIVE_UPDATE_TIMESTAMP</string>
<string name="extra_live_update_value">com.myawesomeapp.extra.LIVE_UPDATE_VALUE</string>
<string name="extra_friend_id">com.myawesomeapp.extra.FRIEND_ID</string>
<!-- Preference Keys -->
<string name="pref_key_update_interval">UPDATE_INTERVAL</string>
<string name="pref_key_theme">THEME</string>
</resources>
</code></pre>
<p>Then, you could access these values from XML as follows:</p>
<pre class="prettyprint"><code><intent-filter>
<action android:name="@string/broadcast_live_update"/>
</intent-filter>
<Preference
android:key="@string/pref_key_update_interval"
... />
</code></pre>
<p><strong>UPDATE Jun 2015: This does not work. The <code>android:name</code> attribute does not take a string resource. It MUST be a string itself. The approach works for Preferences though</strong></p>
<p>And so on. In Java code, you'd access these as:</p>
<pre class="prettyprint"><code>if(getString(R.string.broadcast_live_update).equals(intent.getAction())){
// ...
}
mSharedPref.getLong(getString(R.string.pref_key_update_interval));
</code></pre>
<p><strong>Unfortunately, this solution has all the disadvantages I mentioned in an <a href="#disadvantages">earlier section</a></strong>. </p>
<p>Your <code>constants.xml</code> will quickly become a monolithic clutter. This can be addressed by creating a separate XML file for each type of constant - like <code>broadcasts.xml</code>, <code>pref_keys.xml</code> etc. Even if you do that, you will still be accessing all the resources using <code>@string/blah</code> and <code>R.string.blah</code>.</p>
<p>Also, IDE content assist is still a problem. Your resource names will need to be prefixed with <code>action_</code> or <code>broadcast_</code> or <code>pref_key_</code> etc and finding the key you need could be frustrating.<br>
</p>
<h3>A workable strategy</h3>
<p>Here's a strategy I follow to decide how I should declare these constants:</p>
<ul>
<li>For preference keys, prefer string resources. This is because you are most likely to be building your Settings screens with XML anyway.</li>
<li>For all other key constants, prefer <a href="#split-constant-files">split constant files</a>.</li>
<li>Only if you need to use these from XML, declare them as string resources.</li>
</ul>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-85603328060637566502013-02-01T09:34:00.000+05:302013-02-01T10:52:48.481+05:30Android: Passing an arbitrary object to a custom View<p>So, I came across a situation where I wanted to create a custom <code>View</code> in Android (let's call it <code>MyAwesomeView</code>). I had to work with a couple of constraints:</p>
<ol>
<li>I have to be able to pass in an additional object to <code>MyAwesomeView</code>.</li>
<li>The <code>MyAwesomeView</code> should also be usable from XML.</li>
<li>The <code>MyAwesomeView</code> should be distinct from the application itself - i.e., it should be possible to distribute the <code>MyAwesomeView</code> as a library.</li>
</ol>
<p>To elaborate a bit on the "pass in an additional object" part: <code>View</code> provides three standard constructors using which you can pass in </p>
<ul>
<li>a <code>Context</code>, </li>
<li>an <code>AttributeSet</code> and </li>
<li>an <code>int</code> representing the style.</li>
</ul>
<p>I want to also pass in a <a href="https://github.com/chrisbanes/Android-BitmapCache"><code>BitmapCache</code></a> object since <code>MyAwesomeView</code> uses lots of <code>Bitmap</code>s and I don't want to encounter the dreaded <code>OutOfMemoryError</code> that goes hand in hand with decoding large bitmaps in an Android app. <code>MyAwesomeView</code> decodes a bitmap only if it is not already present in the cache.</p>
<p>The second constraint makes things really difficult. It is possible to pass in additional "configuration" information to a <code>View</code> by <a href="http://developer.android.com/training/custom-views/create-view.html#customattr">creating custom attributes</a>. However, this obviously cannot be used to pass in an object like a <code>BitmapCache</code>.</p>
<h3>Augmenting the <code>Context</code> object with additional information</h3>
<p>This solution I came across is as follows:</p>
<ul>
<li>Define an interface <code>BitmapCacheProvider</code> with a single method <code>provideBitmapCache()</code>;</li>
<li>Make your <code>Activity</code> class implement the interface defined in step 1. Override the interface method to return an appropriate <code>BitmapCache</code> object.</li>
<li>In the constructor of <code>MyAwesomeView</code>, check to see if the context object passed in to implements the <code>BitmapCacheProvider</code> interface. If it does - we're good. If not, then fail fast (or disable cacheing - whatever works for you).</li>
</ul>
<p>In code, here's what this would look like:</p>
<pre class="prettyprint"><code>/**
* Interface to be implemented by the Context (Activity etc) in which `MyAwesomeView` runs
*/
public interface BitmapCacheProvider{
BitmapCache provideBitmapCache();
}
/**
* An example of an Activity that implements BitmapCacheProvider
*/
public class MyActivity extends Activity implements BitmapCacheProvider{
//... Life-cycle methods of the Activity here
@Override
public BitmapCache provideBitmapCache(){
//Get your instance of bitmapcache here - probably from your Application
BitmapCache bitmapCache = ...;
return bitmapCache;
}
}
/**
* Custom View that uses an additional object (BitmapCache) for its configuration.
*/
public class MyAwesomeView extends View{
private BitmapCache mBitmapCache;
public MyAwesomeView(Context context){
init(context, null, 0);
}
public MyAwesomeView(Context context, AttributeSet attrs){
init(context, attrs, 0);
}
public MyAwesomeView(Context context, AttributeSet attrs, int style){
init(context, attrs, style);
}
private void init(Context context, AttributeSet attrs, int style){
try{
/*
* Try casting the contex to BitmapCacheProvider.
*
* If the required interface is not implemented,
* it'll throw a ClassCastException
*/
mBitmapCache = ((BitmapCacheProvider) context).provideBitmapCache();
} catch(ClassCastException e){
throw new ClassCastException(context.toString()
+ " must implement BitmapCacheProvider");
}
//At this point, we have the BitmapCacheObject which we can use for further processing.
}
}
</code></pre>
<h3>Conclusion:</h3>
<p>What we saw in this post was how it is possible to create a custom <code>View</code> in Android, that can take in an arbitrary object in its constructor - and still be usable from XML. Admittedly, it is a bit round-about, but it has its benefits. Here are a few other points worth considering if you are following this approach:</p>
<ul>
<li>In this example, I just augmented the main <code>Activity</code> with the desired <code>interface</code>, but you might need to do this for other classes. Basically, the <code>Context</code> that is passed in to the custom <code>View</code> constructor must be enhanced to implement the interface. What this context is depends on how you are including the custom <code>View</code>.</li>
<li>You might argue that the BitmapCache should be part of the custom <code>View</code> and not passed in to it by the application. This depends on the use case. If you have multiple custom Views that require Bitmap cacheing (as is the case with my app), it probably makes sense for the app to maintain the cache. We might not want too maintain too many caches lest the cache overhead cancels out any benefits we derive from having the cache in the first place!</li>
</ul>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-80796742341062883442013-01-29T10:00:00.000+05:302013-01-30T11:11:55.288+05:30Android: is onDestroy the new onStop?<p>Conventional Android development logic dictates that if there is some action you want to perform (or rather, stop performing) when your <code>Activity</code> is no longer visible to the user, do it in <code>onStop()</code>. Likewise, if there is some action you want to restart performing when the user restarts interacting with your <code>Activity</code>, do it in <code>onStart()</code>. The disadvantage of this approach, of course, is that it wouldn't play well with device orientation changes. </p>
<p>This post explores a couple of solutions to this problem, and concludes that there are cases where one has no choice but to postpone the actions that would be ideally taken in <code>onStop()</code>, to <code>onDestroy()</code>.</p>
<h3>A trivial (incorrect) example</h3>
<pre class="prettyprint"><code>public TrivialIncorrectActivity extends Activity{
//onCreate() and other life-cycle overrides like onResume() go here ...
@Override public void onStart(){
super.onStart();
startMakingThatPeriodicRestCall();
}
@Override public void onStop(){
super.onStop();
stopMakingThatPeriodicRestCall();
}
// ... Other life-cycle overrides like onDestroy() go here
}
</code></pre>
<p>This example is incorrect. Every time the user rotates the device, your app would stop making a REST call and then again start making the call. Not good at all.</p>
<h3><code>setRetainInstance</code> to the rescue . . .</h3>
<p>API 11 introduced the Fragment API, and along with it, the <a href="http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)">setRetainInstance</a> method, which is also usable with older versions of Android by means of the <a href="http://developer.android.com/tools/extras/support-library.html">support library</a>. You can go through the documentation to understand the effect of a <code>setRetainInstance(true)</code>. Essentially, when a configuration change is happening, even though the hosting <code>Activity</code> is being re-created, the <code>Fragment</code> instance is not destroyed.</p>
<p>So, this allows us to improve upon our previous example. </p>
<pre class="prettyprint"><code>public IncorrectRotationTolerantActivity extends FragmentActivity{
private static final String TAG_RETAIN_FRAGMENT = "RetainFragment";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState == null){
getSupportFragmentManager().beginTransaction()
.add(IncorrectRetainFragment.newInstance(), TAG_RETAIN_FRAGMENT).commit();
}
}
}
public class IncorrectRetainFragment extends Fragment{
public IncorrectRetainFragment(){}
public static IncorrectRetainFragment newInstance(){
IncorrectRetainFragment frag = new IncorrectRetainFragment();
frag.setRetainInstance(true);
return frag;
}
@Override
public void onStart() {
super.onStart();
startMakingThatPeriodicRestCall();
}
@Override
public void onStop() {
super.onStop();
stopMakingThatPeriodicRestCall();
}
}
</code></pre>
<p>This code snippet still doesn't do what we want it to do. It does <strong>not</strong> prevent re-making that REST call during orientation changes. Why?</p>
<p>Because, <code>setRetainInstance</code> doesn't prevent a Fragment's <code>onStop()</code> from being called - it just prevents <code>onDestroy()</code> from being called. So, even if you ask for a Fragment instance to be retained across configuration changes, the <code>onStop()</code> method of the Fragment is always still called when the device is rotated.</p>
<h3><code>onDestroy()</code> is the new <code>onStop()</code></h3>
<p>To fix the problem, postpone stopping the REST call to the <code>onDestroy()</code> of the Fragment. Similarly, start making the call in <code>onCreate()</code> instead of in <code>onStart()</code>, since <code>onCreate()</code> is not called when the device is rotated, but <code>onStart()</code> is.</p>
<pre class="prettyprint"><code>public RotationTolerantActivity extends FragmentActivity{
private static final String TAG_RETAIN_FRAGMENT = "RetainFragment";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState == null){
getSupportFragmentManager().beginTransaction()
.add(RetainFragment.newInstance(), TAG_RETAIN_FRAGMENT).commit();
}
}
}
public class RetainFragment extends Fragment{
public RetainFragment(){}
public static RetainFragment newInstance(){
RetainFragment frag = new RetainFragment();
frag.setRetainInstance(true);
return frag;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onStart(savedInstanceState);
startMakingThatPeriodicRestCall();
}
@Override
public void onDestroy() {
super.onStop();
stopMakingThatPeriodicRestCall();
}
}
</code></pre>
<p>This seems so semantically wrong though. <code>onDestroy()</code> represents the end of the <em>entire lifetime</em> of an Activity/Fragment and what we really wanted to do was monitor the <em>visible lifetime</em>. Also, there is no guarantee that <code>onDestroy()</code> will ever be called. If you really try out this example on a phone or emulator, chances are that you'll never see the Rest call being stopped - at least not right away.</p>
<h3>A more correct, more restrictive solution:</h3>
<p>There exists another solution to this problem - but it works only on API 11 and later, because it uses methods introduced in API 11 - <code>isChangingConfigurations()</code> and <code>getChangingConfigurations()</code>.</p>
<pre class="prettyprint"><code>public RotationTolerantActivity extends FragmentActivity{
private boolean mRotated;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Boolean nonConfigState =
(Boolean)getLastCustomNonConfigurationInstance();
if (nonConfigState == null) {
mRotated = false;
} else {
mRotated = nonConfigState.booleanValue();
}
}
@Override
public void onStart(){
super.onStart();
if(!mRotated){
startMakingThatPeriodicRestCall();
}
}
@Override
public void onStop(){
super.onStop();
mRotated = false;
if (isChangingConfigurations()) {
int changingConfig = getChangingConfigurations();
if ((changingConfig & ActivityInfo.CONFIG_ORIENTATION) == ActivityInfo.CONFIG_ORIENTATION) {
mRotated = true;
}
}
if(!mRotated){
stopMakingThatPeriodicRestCall();
}
}
@Override
public Object onRetainCustomNonConfigurationInstance() {
return mRotated ? Boolean.TRUE : Boolean.FALSE;
}
}
</code></pre>
<p>This solution is semantically correct, and works as expected. However, <strong>it only works on API 11 and higher, <em>even though we extend <code>FragmentActivity</code> from the support library</em> </strong>.</p>
<h3>Bonus: Why <code>onStop()</code> and not <code>onPause()</code>?</h3>
<p>The keen reader would have observed that this post talks about stopping un-needed tasks in <code>onStop()</code>and not <code>onPause()</code> - even though <code>onPause()</code> is the only one of these methods that is guaranteed to be called. Remember that after <code>onPause()</code> is called, the process could be killed in order to reclaim memory and thus <code>onStop()</code> and <code>onDestroy()</code> might never be called.</p>
<p>Yet, this entire post insists on using <code>onStop()</code> to stop un-needed tasks. The reason for this lies in the technique used in my library <a href="https://github.com/curioustechizen/android-app-pause">android-app-pause</a>. Unfortunately, this library in its current form does not handle device orientation changes correctly. This will be fixed in a future release though.</p>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-26376560992572943072013-01-05T21:40:00.001+05:302013-01-10T12:03:47.811+05:30Extensibility and Immutability in Java<h3>Objective:</h3>
<blockquote>
<p><strong>To devise a way to make thread-safe, a Java class designed to be extensible.</strong></p>
</blockquote>
<h3>Introduction:</h3>
<p><em>Effective Java, Second Edition: Item 15</em> says <strong>"Minimize Mutability"</strong>. One should always try to make a class immutable. This has several advantages that I will not go over here (Since <em>Effective Java</em> explains it all). I will however point out one of those advantages since it is central to this discussion: </p>
<blockquote>
<p><strong>Making a class immutable is the easiest way to ensure that the class is thread-safe.</strong></p>
</blockquote>
<p>There is however a problem: to make a class <em>truly immutable</em>, you must prevent it from being sub-classed. Either the class must be declared <code>final</code>, or it should have a <code>private</code> constructor and provide <code>static</code> factory methods instead of constructors. The reasons for this are outlined in <em>Effective Java</em>. The basic premise is that a sub-class can violate the immutability guarantees. </p>
<p>This must-not-be-subclassed restriction may be fine if you are applying immutability to some <em>value object</em> like <code>User</code>, <code>Point</code>, <code>Account</code> etc. However, the same requirement turns out to be overly restrictive if you are applying the concept to <em>logic classes</em>. This is because logic classes are often meant to be customized by extension. </p>
<h3>A strongly-immutable logic class:</h3>
<p>As an example of a logic class, consider the following ReportGenerator:</p>
<pre class="prettyprint"><code>public final class ReportGenerator{
private final DatabaseLayer mDatabaseLayer;
private final PresentationLayer mPresentationLayer;
public ReportGenerator(DatabaseLayer db, PresentationLayer pres){
this.mDatabaseLayer = db;
this.mPresentationLayer = pres;
}
public void generateMonthlyReport(User user){
Report report = mDatabaseLayer.getReport(user);
mPresentationLayer.present(report);
}
}
</code></pre>
<p>The other classes have been ommitted for brevity. Assume that <code>DatabaseLayer</code> and <code>PresentationLayer</code> classes are themselves immutable. This makes <code>ReportGenerator</code> <strong>strongly immutable</strong> and hence, thread-safe.</p>
<p>Now, suppose in the next phase of the project, you need to add a way to generate a historical report. The easiest way that comes to mind is to inherit from <code>ReportGenerator</code>. Unfortunately, we cannot do this since in order to make <code>ReportGenerator</code> immutable, we have declared it <code>final</code>. One possible approach to solving this issue is making <code>ReportGenerator</code> <strong>weakly immutable</strong>. This is discussed in the next section.</p>
<h3>A weakly-immutable logic class:</h3>
<p>One can relax the restriction that an immutable class must not be extensible, while still maintaining the guarantees, <strong>provided the sub-class adheres to the established contract</strong>. This is done by removing the <code>final</code> modifier from the class declaration, and making all fields <code>protected final</code>, or keep them <code>private final</code> and provide getters which we then use in the sub-classes. Both these approaches are shown in the code below.</p>
<pre class="prettyprint"><code>public class ReportGenerator{
protected final DatabaseLayer mDatabaseLayer; //protected field approach
private final PresentationLayer mPresentationLayer; //private field with accessor approach
public ReportGenerator(DatabaseLayer db, PresentationLayer pres){
this.mDatabaseLayer = db;
this.mPresentationLayer = pres;
}
public PresentationLayer getPresentationLayer(){
return this.mPresentationLayer;
}
public void generateMonthlyReport(User user){
Report report = mDatabaseLayer.getReport(user);
mPresentationLayer.present(report);
}
}
</code></pre>
<p>We can now sub-class this as follows:</p>
<pre class="prettyprint"><code>public class HistoricalReportGenerator extends ReportGenerator{
public HistoricalReportGenerator(DatabaseLayer db, PresentationLayer pres){
super(db, pres);
}
public void generateHistoricalReport(User user, Duration duration){
Report historicalReport = mDatabaseLayer.getReport(user, duration);
getPresentationLayer().present(historicalReport);
}
}
</code></pre>
<p>We could also have added more <code>protected final</code> fields to the sub-class if needed. </p>
<p>What we now have is a weakly immutable class. <strong>This class is immutable as long as sub-classes adhere to the contract</strong>. It is a good idea to establish in the class javadoc, the expectation that sub-classes <strong>MUST</strong> preserve the same weak immutability restrictions that this class adheres to. If a sub-class willfully violates the contract, then the logic class cannot be depended upon to work correctly.</p>
<p>Here's an example to how to establish this contract:</p>
<pre class="prettyprint"><code>/**
* The logic class that generates the report.
* ... ...
* <br/><br/>
* This class is <em>weakly immutable</em>. It has been kept open for
* extensibility. Sub-classes <strong>MUST</strong> preserve the immutability
* guarantees of this class. In particular, they must have only immutable
* fields; and must not override any of the methods defined in this class to
* return a mutable reference.
*
*/
public class ReportGenerator{
//Class body omitted.
}
</code></pre>
<p>Since immutability is enforced by documentation rather than by the compiler, this is an acceptable compromise. It allows us to easily create thread-safe classes that are also extensible. This makes writing API's and frameworks that much easier.</p>
<h3>Thread-safety is more than Immutability:</h3>
<p>Of course, making a class immutable is not the only way to make a class thread-safe. A mutable class can be written such that it is thread-safe too. It is often desirable for an object to change its state during the execution of a program. How that is done is beyond the scope of this article. I suggest looking at <em>Java Concurrency In Practice</em> for details on this topic.</p>
<h3>Extending the logic class by Composition:</h3>
<p>There exists an alternative way to extend the functionality of <code>ReportGenerator</code> that does not involve inheriting from it: <strong>"Favor Composition over Inheritance"</strong> (<em>Effective Java, Second Edition, Item 16</em>). For completeness, I present the code for this approach here. Do note that this example uses the strongly immutable form of <code>ReportGenerator</code>.</p>
<pre class="prettyprint"><code>public final class ReportGenerator{
private final DatabaseLayer mDatabaseLayer;
private final PresentationLayer mPresentationLayer;
public ReportGenerator(DatabaseLayer db, PresentationLayer pres){
this.mDatabaseLayer = db;
this.mPresentationLayer = pres;
}
public PresentationLayer getPresentationLayer(){
return this.mPresentationLayer;
}
public DatabaseLayer getDatabaseLayer(){
return this.mDatabaseLayer;
}
public void generateMonthlyReport(User user){
Report report = mDatabaseLayer.getReport(user);
mPresentationLayer.present(report);
}
}
public final class HistoricalReportGenerator{
private final ReportGenerator mReportGenerator;
public HistoricalReportGenerator(ReportGenerator reportgen){
this.mReportGenerator = reportgen;
}
public ReportGenerator getReportGenerator(){
return this.mReportGenerator;
}
public void generateHistoricalReport(User user, Duration duration){
Report historicalReport = mReportGenerator.getDatabaseLayer().getReport(user, duration);
mReportGenerator.getPresentationLayer().present(report);
}
}
</code></pre>
<p>This approach works fine when the class hierarchy is only a couple of levels deep. If it gets deeper than that, then getting a handle to the members of the base class becomes unwieldy. For example, suppose we have the following:</p>
<pre class="prettyprint"><code>public class AnnualReportGenerator extends HistoricalReportGenerator
public class LeapYearReportGenerator extends AnnualReportGenerator
</code></pre>
<p>Now imagine a method in <code>LeapYearReportGenerator</code> needs access to the <code>DatabaseLayer</code> object. The code for this would look lik:</p>
<pre class="prettyprint"><code>mAnnualReportGenerator().getHistoricalReportGenerator().getReportGenerator().getDatabaseLayer();
</code></pre>
<p>This is clearly something you want to avoid. With the composition approach, you also lose the runtime polymorphism advantage.</p>
<h3>Conclusion</h3>
<p>To summarize what this article discussed:</p>
<blockquote>
<ul>
<li>The easiest way to make a class thread-safe is to make it immutable.</li>
<li>Strong immutability closes the door on extensibility.</li>
<li>It is often convenient to make a class weakly immutable. This allows it to be sub-classed.</li>
<li>If you make an immutable class extensible, clearly establish in the javadoc, the contract that sub-classes must preserve the immutability guarantees.</li>
</ul>
</blockquote>
<p>Other than these observations, we also saw that:</p>
<blockquote>
<ul>
<li>Immutability is not the only way to achieve thread-safety, and in fact immutability is not always desirable.</li>
<li>Instead of inheriting from a weakly immutable class, one can also extend the functionality by composing a class with a strongly immutable object as its member. This has its own pros and cons - and both approaches must be evaluated before deciding on one.</li>
</ul>
</blockquote>
<script>prettyPrint()</script>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-74685364981000736082012-12-18T11:00:00.000+05:302013-01-10T12:06:48.622+05:30Code Smells: Calling Life-Cycle Methods of Program Components Explicitly<p>Here is some code I see that sets off alarm bells clanging in my head: </p>
<blockquote>
<p>Explicitly calling life-cycle methods of components <strong>that are outside your control</strong>. </p>
</blockquote>
<p>Since that sounds oh-so-generic, let me illustrate by way of example.</p>
<p>Assume you are writing a <code>Servlet</code> and your implementation doesn't care whether the request was a POST or a GET (in the current RESTful world, this should never be the case, but let's keep that aside for the purposes of this post). So, the following would appear to be a reasonable implementation:</p>
<pre class="prettyprint lang-java prettyprinted" style=""><code>public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
//Handle the request
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
doGet(req, resp); //Just call doGet
}
}
</code></pre>
<p>I would never do this though. This is because <code>doGet</code>, <code>doPost</code> and the other <code>doXXX</code> methods are life-cycle methods of the <code>Servlet</code>. I have no control over when and how the servlet engine calls them. I also have no control over what the engine does once these methods return. It is possible that the engine performs some house-keeping tasks once a <code>doGet</code> returns, and that action could be different from what is done once a <code>doPost</code> returns.</p>
<p>It is really a simple matter of extracting the "common functionality" between such life cycle methods into a method and calling that method.</p>
<pre class="prettyprint lang-java prettyprinted" style=""><code>public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
handleRequest(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
handleRequest(req, resp);
}
/**
* Method that extracts out the common functionality between GET and POST requests
*/
private void handleRequest(HttpServletRequest req, HttpServletResponse resp){
//Handle the request
}
}
</code></pre>
<h4>What if the life cycle methods are in an Interface?</h4>
<p>One opinion that came up in a discussion was that it is safe to call other life-cycle methods if they are in an <code>interface</code> as opposed to a <code>class</code>. Note that the above code sample extends <code>javax.servlet.http.HttpServlet</code> which is an <code>abstract class</code> as opposed to the base <code>javax.servlet.Servlet</code> which is an <code>interface</code>. This has come up specially while discussing callbacks. </p>
<p>I disagree with this opinion since it assumes that any book-keeping has to be performed by the same (possibly <code>abstract</code>) class that denotes the life-cycle component. This is not true. Take an imaginary UI toolkit for example, which has a <code>Pane</code> as a UI element. Now, assume an interface for handling interaction callbacks:</p>
<pre class="prettyprint lang-java prettyprinted" style=""><code>interface InteractionListener{
public void onClick();
public void onRightClick();
public void onLongClick();
public void onDoubleClick();
}
</code></pre>
<p>In this case again, assume that you want the same action to be performed on long-click and right-click. So, you might be tempted to do this:</p>
<pre class="prettyprint lang-java prettyprinted" style=""><code>Pane pane = // ...
pane.setInteractionListener(new InteractionListener(){
public void onClick(){
//Handle single-click
}
public void onRightClick(){
//Handle right-click
}
public void onLongClick(){
onRightClick();
}
public void onDoubleClick(){
//Handle double-click
}
});
</code></pre>
<p>This is <em>still</em> wrong. Yes- <code>InteractionListener</code> is an interface and there is no way it can have a concrete method that might perform house-keeping tasks. However, you have no control over how the UI toolkit engine invokes the call-backs. You also have no control over what action the engine takes <em>after</em> your <code>onXXXClick()</code> methods return. The solution, again is exactly the same as before: extract the common code into a method which you then invoke from both <code>onLongClick()</code> and <code>onRightClick()</code>.<br />
</p>
<h4>Conclusion</h4>
<p>Avoid calling one component life-cycle method from another, when the component in question is outside your control. This could lead to unpredictable behavior. Simply refactor the common behavior into a method and call that method from both life-cycle call-backs.</p>
<p>A few other instances where I have seen this sort of code:</p>
<ul>
<li>
<p>Android's <a href="http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html"><code>SqliteOpenHelper</code></a>. In the <code>onUpgrade()</code> method, you probably want to take a backup of data, drop the tables, add new columns, and then re-create the tables. The implementation often looks like this:</p>
<pre class="prettyprint lang-java prettyprinted" style=""><code>public class MySqliteOpenHelper extends SqliteOpenHelper{
public void onCreate(SQLiteDatabase db){
//Use SQL CREATE TABLE statements to create the tables.
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
/*
* 1. Take backup of data
* 2. Drop tables
* 3. Add columns
*
* And finally:
*/
onCreate(db); //This is not right.
}
}
</code></pre>
<p>The right way to do this would be:</p>
<pre class="prettyprint lang-java prettyprinted" style=""><code>public class CorrectSqliteOpenHelper extends SqliteOpenHelper{
public void onCreate(SQLiteDatabase db){
createDatabase(db);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
/*
* 1. Take backup of data
* 2. Drop tables
* 3. Add columns
*
* And finally:
*/
createDatabase(db);
}
private void createDatabase(SQLiteDatabase db){
//Use SQL CREATE TABLE statements to create the tables.
}
}
</code></pre>
</li>
</ul>
<p>I will re-visit this post and add more instances as and when I come across them.</p>
<script>prettyPrint()</script>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-49399620545742372532012-12-03T23:13:00.000+05:302012-12-09T22:16:33.283+05:30Android: "Application level" Pause and Resume<h3>Update</h3>
<p>I have created an open source library using the concepts presented in this post. You can directly use the library to create your apps. Get it at <a href="https://github.com/curioustechizen/android-app-pause">android-app-pause</a> on github</p>
<h3>Introduction</h3>
<p>I have often come across questions on StackOverflow and the android-developers google group about an <code>Application</code>-level <code>onPause()</code> and <code>onResume()</code>. In this post, I present one of the ways of achieving such functionality. But before that, what exactly do I mean by an app-level <code>onPause()</code>?</p>
<p>After all, an Android app consists of multiple components, several of which might be in the background. There could be <code>Service</code>s, <code>Thread</code>s, <code>BroadcastReceiver</code>s, scheduled <code>Alarm</code>s. How do these figure in a "paused" app? Well, here's my definition of an app being paused for the purposes of this post:</p>
<blockquote>
<p>An app is considered to be paused when the app is no longer visible to the user. By definition, this means that when an app is paused, <em>none of the Activities that belong to the app</em> are visible to the user.</p>
</blockquote>
<p>In my opinion, this is a fair definition since this would typically be the point when the app wishes to "pause" any background work it does. For example, an app might wish to cancel all scheduled alarms, or stop making HTTP calls when it knows that the user is no longer interacting with the app.</p>
<blockquote>
<p>Similarly, an app is considered to be resumed when at least one <code>Activity</code> from the app is visible to the user.</p>
</blockquote>
<p>This is the point at which the app can re-establish HTTP communication, re-schedule alarms and the like.</p>
<h3>TL;DR</h3>
<p>I got this idea from <a href="http://stackoverflow.com/a/7924855/570930">this answer</a> that I gave on stackoverflow. The basis of this approach is that when an Activity starts another, both of them <a href="http://developer.android.com/guide/components/activities.html#CoordinatingActivities">undergo lifecycle changes</a> <strong>in a predictable fashion</strong>. The series of steps to follow to achieve the app-level pause and resume functionality is as follows:</p>
<blockquote>
<ol>
<li>Create a bound <code>Service</code> (let's call this <code>AppActiveService</code>).</li>
<li>In the <code>onStart()</code> of every <code>Activity</code> of your app, bind to <code>AppActiveService</code>.</li>
<li>In the <code>onStop()</code> of every <code>Activity</code> of your app, unbind from <code>AppActiveService</code>.</li>
<li>The <code>onDestroy()</code> method of <code>AppActiveService</code> represents the point when your app is "pausing"; while the <code>onBind()</code> method represents the point when your app is "resuming". Put the code you want to be run when your app "goes to the background" in <code>AppActiveService</code>'s <code>onDestroy()</code> method.</li>
</ol>
</blockquote>
<p>To make things even simpler, you can put all the code above in a <code>BaseActivity</code> for your application and have all your other Activities inherit from this <code>BaseActivity</code>.</p>
<p>If you follow the steps above, the <code>AppActiveService</code> will have at least one <code>Activity</code> bound to it as long as your app is visible to the user. When this condition is false, no <code>Activity</code> is bound to the <code>Service</code>, at which point its <code>onDestroy()</code> is called.</p>
<p>Do note that we are using <code>onStop()</code> and not <code>onPause()</code> to un-bind from the <code>Service</code>. If you were to use <code>onPause()</code>, then there would be zero components bound to <code>AppActiveService</code> even as you are switching from one <code>Activity</code> to the other within your own app.</p>
<h3>Gotchas</h3>
<p>One gotcha in this approach is: What happens if your app "starts another app" using an <code>Intent</code>? No <code>Activity</code> from your app will be visible to the user - thus triggering an app-pause. Whether this is acceptable or not depends on your use case.</p>
<h3>Conclusion</h3>
<p>I plan to publish the code for this procedure as a library or at least as a gist on GitHub. Before that, I'm looking for feedback on how the code can be improved and made more robust. Have you come across the need to know when your app as a whole is "going away"? How have you solved the problem?</p>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-8131488125712736542012-09-29T12:19:00.001+05:302012-10-03T18:12:46.977+05:30Google Play Services, and Why We Still Need AccountManager<h3>Introduction</h3>
<p>Recently, Google has <a href="http://android-developers.blogspot.ca/2012/09/google-play-services-and-oauth-identity.html">started rolling out</a> the widely awaited <a href="https://developers.google.com/android/google-play-services/">Google Play Services</a>, announced during Google I/O 2012. One of the major pieces of Google Play Services is the <code>GoogleAuthUtil</code>. The principal problem that this component solves is OAuth. Up until now, writing an Android app that requires OAuth has been <strong>complex</strong> and <strong>non-standard</strong>. </p>
<ul>
<li>Complex, because you need perform the whole OAuth dance behind the scenes (not specific to Android, mind you). </li>
<li>Non-standard because the app developers ended up displaying their own custom screens for choosing the account to be used for OAuth. Also, the OAuth scopes are specific to the identity provider; and this led to displaying the <em>raw oauth scope strings</em> in some OAuth confirmation screens rather than a user-friendly description of the scope. </li>
</ul>
<p>The <a href="https://developer.android.com/reference/android/accounts/AccountManager.html"><code>AccountManager</code> framework</a> did some of the heavy lifting and attempted to address both the problems. However, it met with limited success on both counts. Which is why, when the <code>GoogleAuthUtil</code>, and the <code>AccountPicker</code> were previewed at IO2012, I was jumping in excitement. If you want your app to use OAuth with Google, then <code>GoogleAuthUtil</code> makes life a whole lot simpler.</p>
<h3>Caveat</h3>
<p>But, therein lies the caveat. <strong><em>It only applies to Google Accounts</em></strong>. One could argue that any Android device that has Google Play Services also has at least one Google account - so this is not a big deal. However, remember that many Android apps are actually just one of the ways of accessing a (possibly OAuth-protected) web service. The web service itself might offer several identity providers for the user to sign up, log in or authorize. Restricting that to just the Google account on the Android version of the app doesn't make sense.</p>
<p>What is really required is for more identity providers to leverage the <code>AccountManager</code> framework in Android. Admittedly, that is not so straightforward. Not only does it involve writing an <code>AccountAuthenticator</code>, there are some pieces specific to identity provider and <strong>there is no go-to place to publish the documentation for these provider-specific pieces</strong>. </p>
<p>Suppose I wanted to write an app that allows users to sign in with their Google, Facebook or Twitter accounts. Google is easy (it has been easy even before Play Services!). But what about the rest? How do I know what the <code>accountType</code> for Twitter is? How do I know the valid values for <code>features</code> parameter for Twitter? </p>
<p>But the problem doesn't stop there. Apparently, some third-party services <strong>require you to use their OAuth API to sign the user in</strong>. This is stated explicitly, as part of the terms of services. I noticed this when I was trying out a third party twitter client. I already had Twitter's official client installed, and hence my twitter account was available in the "Accounts" settings. Still, I had to enter my twitter credentials in a WebView. The third-party twitter client did not use AccountManager to log me in. I wrote to the developer about it and I was informed that Twitter required this as part of their terms of service.</p>
<h3>Solution (?)</h3>
<p>I really think third party identity providers (at least the big ones) should make an effort to leverage <code>AccountManager</code> framework of Android. This may be additional work - but just look at the size of the customer base they are targetting. With the new <code>AccountPicker</code>, the end user experience for using OAuth with Google is a breeze. It makes the traditional "log in using a web page" seem like a stone-age UX. The driving principle should be:</p>
<blockquote>
<p><strong>An end user should never be forced to enter the credentials for an account that is already present in the "Accounts" settings screen</strong></p>
</blockquote>
<p>Furthermore, it may project Google in a bad light since it may give the impression that Google is trying to make the UX good for its own services while leaving others in the lurch - which is not true.</p>
<h3>Conclusion</h3>
<p>In a nutshell: </p>
<ul>
<li>Google Play Services (in particular <code>AccountPicker</code>) = <strong>Good</strong> - for Google Accounts.</li>
<li>Third party identity providers and OAuth providers: WebView = <strong>Bad</strong>. Please use <code>AccountManager</code> and <code>AbstractAccountAuthenticator</code>.</li>
</ul>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-88271110483416544222012-07-26T20:59:00.000+05:302012-07-26T20:59:40.390+05:30That's NOT Fragmentation; But then What Is?<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<p>Of late, much has been said and debated regarding the fragmentation "problem" in Android. People who know me know that I'm a BIG fan of Android - as a user and as a developer. However, I do admit that Android is fragmented. That, in itself is <a href="http://www.vogella.com/blog/2012/07/17/why-the-missing-device-fragmentation-is-hurting-the-iphone/">not such a bad thing</a>. But, this fragmentation is making my life as a developer that much more difficult. That's the bad thing.</p>
<p>Having said that, I get to read and here things like this a lot. These all belong to a category I like to call "What Fragmentation is <strong>NOT</strong>".</p>
<blockquote>
<p>Oh! There's 4-inch phones, 7-inch tabs and 10-inch tabs? <strong>Damn! Fragmentation!</strong></p>
</blockquote>
<p>OR</p>
<blockquote>
<p>Urghh! So many different device manufacturers? So many thousands of device models? They won't all have the same hardware and capabilities :-( <strong>Damn! Fragmentation!</strong></p>
</blockquote>
<p>Try This</p>
<blockquote>
<p>What? Every release of Android has its own theme and look&feel? <strong>Damn! Fragmentation!</strong></p>
</blockquote>
<p>All of this makes me go "Oh No! Not again!" I wonder how developers don't realize that these factors are not limitations - they are an opportunity: to get your app to audiences you wouldn't have thought possible. Android platform has armed developers with great tools to address these factors.</p>
<ul>
<li>The amazing <a href="http://developer.android.com/guide/topics/resources/overview.html">resources framework </a> allows you to adapt to a wide variety of configurations with little or no code. You can optimize your app for phone, tablet, portrait, layout, night mode, keyboard mode, dock mode, different languages and what not by simply providing alternate resources.</li>
<li>Then, there's the theme inheritance with which you can customize the look and feel of your app without looking out of place on the particular platform version.</li>
<li>If your app requires a particular capability to work; or if it cannot function in certain configurations, you can use manifest filtering to prevent it from being available to devices that don't match your criteria.</li>
</ul>
<p>All the above rants, can then be attributed to developers <strong>not knowing the framework</strong> and the tools properly. These have <em>nothing to do with fragmentation</em>.</p>
<hr />
<p>There are some problems, though, that have the potential of requiring developers to spend considerably more effort if they want their apps to target a large percentage of Android devices in the wild. A sampling of such problems follows.<br />
</p>
<h3>RTSP Streaming:</h3>
<p>Getting a simple RTSP video stream to play on even the more popular devices using Android's <a href="http://developer.android.com/guide/topics/media/mediaplayer.html">MediaPlayer</a> framework is an uphill task (I've tried and basically given up). As per the specs it should "just work", but implementations haven't adhered strictly to the specs. </p>
<p>Now, <strong> <strong><em>That's</em></strong> fragmentation</strong>.<br />
</p>
<h3>Rapid Deprecations:</h3>
<p>UI and design patterns that were previously <em>suggested by the Android team</em> have suddenly fallen out of favor and are now deprecated, only to be replaced with new patterns (yes, Android Design Guide, I'm looking at you). Examples include <a href="http://developer.android.com/guide/topics/ui/actionbar.html">ActionBar</a>, and <a href="https://groups.google.com/d/topic/android-developers/8M0RTFfO7-M/discussion">the AsyncTask punishment</a>.</p>
<p>The fact that device manufacturers haven't exactly kept up with the pace of Android platform version releases doesn't help. For example, as of July 2, 2012, the percentage of devices that support ActionBar functionality <em>natively</em> <a href="http://developer.android.com/about/dashboards/index.html">is just 13%</a>.</p>
<p>The Android team, and the community have tried to bridge the gap by coming up with libraries that allow you to use the new features on the old versions (via <a href="http://developer.android.com/tools/extras/support-library.html">Android Compatibility Library</a>, <a href="http://actionbarsherlock.com/">ActionBar Sherlock</a> etc), but these don't completely solve the problem. There are still gaps, and if you want to develop an app that both follows the new patterns <em>and</em> is truly well-behaved on even 75% of the installed base, you have to roll your sleeves and get your hands dirty.</p>
<p>Now, <strong> <strong><em>That's</em></strong> fragmentation</strong>.<br />
</p>
<h3>Very Basic Changes in the Framework:</h3>
<p>Since HoneyComb (Android 3.0), the dedicated hardware <a href="http://android-developers.blogspot.in/2012/01/say-goodbye-to-menu-button.html">"Menu" key has been dumped</a> in Android, to be replaced with an overflow menu in the ActionBar. This seems like a simple problem, until you come across problems like <a href="http://commonsware.com/blog/2012/06/08/removing-rogue-menus.html">this one</a>.</p>
<p>You can't even be confident that your erstwhile awesome app will display that menu properly across all devices.</p>
<p>Now, <strong> <strong><em>That's</em></strong> fragmentation</strong>.</p>
<p>The way you are supposed to use the Back Button has been changed and made <a href="http://www.androiduipatterns.com/2012/07/i-was-watching-navigation-in-android.html">all the more confusing</a> to both developers and end users. There was even a talk at the recent Google IO conference in which half an hour was spent explaining the reasoning behind the back button.</p>
<p>To balance the way the back button is supposed to work in various versions of the platform, with the way <em>you</em> want it to work might take quite a lot of effort (especially since the compatibility API's <a href="http://developer.android.com/reference/android/support/v4/app/TaskStackBuilder.html">don't really do the job</a> here).</p>
<p>Now, <strong> <strong><em>That's</em></strong> fragmentation</strong>.<br />
</p>
<h3>Patent-induced inconsistencies:</h3>
<p>We've all got used to the "Chooser" displayed by Android whenever you click on, say, a link in an e-mail. This chooser allows you to select the app that you would use to display the link (probably a list of browsers installed on your device).</p>
<p>Pretty basic stuff, right? Well, this may no longer be the case. As a result of a patent issues, at least one manufacturer <a href="http://commonsware.com/blog/2012/07/24/linkify-problem-detection-mitigation.html">has modified this behavior</a>. This is bad news for app developers that depend on this feature for their app to be even discovered. Work-arounds exist but are very very round-about. Also, what if another manufacturer follows some other approach to get past the patent problem?</p>
<p>Now, <strong> <strong><em>That's</em></strong> fragmentation</strong>.</p>
<hr />
<p>There are other issues I can point out, but I guess I've made my point (at least to all two of you who've made it this far). Luckily, most of these problems are likely to be contained in the near future. This makes sense if you look at the fact that Android is still a maturing platform. The team behind it is bound to realize how some of the earlier decisions were wrong and it is good for the platform and ecosystem if they take steps to correct the mistakes. For example:</p>
<ul>
<li>The AsyncTask, ActionBar and Menu key problems I mentioned will probably not be a problem once we have more devices running ICS and above.</li>
<li>The Back Button and other issues surrounding navigation guidelines are also likely to be eliminated once we have more developers developing apps that follow the <em>new</em> guidelines <strong><em>consistently</em></strong>. I also don't expect Google to make any more drastic changes in these areas in the near future.</li>
<li>Even the MediaPlayer framework inconsistencies are bound to shrink with more adoption of the newer platform releases.</li>
<li>At Google IO 2012, Google announced the PDK (Platform Developers' Kit) aimed at shortening the gap between the announcement of a new platform release; and device manufacturers rolling out phones or updates with the new release. Believe me - this is <strong>GOOD!</strong></li>
</ul>
<p>That leaves the issues related to patent and other legal stuff. There's not much Google or any device manufacturer can do in that space, when evil and jealous competitors are deciding to abandon innovation and instead pick up cheap means to combat competition, is there?</p>
<hr />
<h3>Conclusion:</h3>
<p>Yes, Android is fragmented. Today, the effort it takes to make your app play well on various versions, and implement all the new guidelines is disproportionate to the gains (that's purely my own opinion). But this won't last.</p>
<p>Once <a href="http://developer.android.com/about/dashboards/index.html">this pie-chart</a> shows a growth in ICS and newer devices, lot of our problems as developers will be minimized. As for fragmentation caused by reasons outside Google's control - well we'll just have to live with it.</p>
</div>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-80918471190928677282012-06-13T08:10:00.000+05:302012-06-13T08:10:34.487+05:30Internationalization in Spirit: Part 3 - Developers<p>This is the third post in a series about the idea behind making software truly global; and why we are not quite there yet. You can read <a href="http://curioustechizen.blogspot.com/2012/03/internationalization-in-spirit.html">Part 1</a> and <a href="http://curioustechizen.blogspot.com/2012/03/internationalization-in-spirit-part-2.html">Part 2</a> to get some context.</p>
<p>It goes without saying that the core of the software world is the development community. The success of any software platform (that could mean programming language/ API/ development stack/ tool/ … ) depends on how well developers take to it. Every platform out there has gone all out trying to woo not only users, but also developers. There’s documentation, end-to-end samples, fancy tooling, developer fora, mailing-lists, HowTo screencasts, support groups and what not. These days we even have video conferencing wherein the core developers of the platforms interact directly with the community.</p>
<p>The question, then is, is this sufficient to make the platform easier to consume for developers all over the world? From my experience, I would say that there is still lot of scope in this area.</p>
<p>To begin with, there seems to be an unwritten assumption that command over the English language is necessary in order to be a good programmer. This is reflected in</p>
<ul>
<li>the complicated language in use in developer documentation</li>
<li>the “heavy” words used to name program elements (classes, functions, variables .. )</li>
<li>names of frameworks/API’s or the concepts (like design patterns) on which they are based. These are often cool or catchy, but again, they make sense to only a subset of the developers that use them.</li>
</ul>
<p>I argue that this assumption is faulty. It is worth remembering that software development (particularly the services industry) is now big in BRICS countries and also picking up in countries like Argentina, Vietnam, Philippines. Most programmers might have basic English knowledge, but I seriously doubt their having a command over the language.<br />
</p>
<h3>Developer Documentation:</h3>
<p>I believe that currently, there is this thing about making documentation grammatically (and I don't know .. legally, politically, ...?) correct. This comes at the cost of clarity. While a developer who is sufficiently well-versed in English might easily understand the essence of the documentation, it is often confusing for developers who are not so well-versed in English.</p>
<p>Consider the following method doc:</p>
<blockquote>
<p><code>String bestMatch(String text)</code> </p>
<p>Scans the database of known keywords until a match on the supplied text occurs, unless said database is empty, in which case falls back to performing keyword search on description and content fields; in either case returning a best match if found, <code>null</code> otherwise.</p>
</blockquote>
<p>Yes that was correct. But how easy was it to comprehend? Now, consider the same method doc re-written as follows:</p>
<blockquote>
<p><code>String bestMatch(String text)</code></p>
<ol>
<li>
<p>Scans database of known keywords , attempting to match the supplied text with the keyword.</p>
</li>
<li>
<p>If the database is empty, attempts a match on content and description fields.</p>
</li>
</ol>
<p>In both cases, this method returns the best match String if found, <code>null</code> otherwise.<br />
</p>
</blockquote>
<p>My point is, developer documentation should strive to be simple in language. It is always possible to re-word complex sentences by breaking them up into bullet points and the like. </p>
<p>Documentation should avoid using subtle grammar or obscure language constructs where possible. Needless "smart" wordplay is a strict no-no. Documentation is not a place to show off one's language skills, there are other forums well-suited for that! </p>
<h3>Samples:</h3>
<p>Back in college, we mostly used <code>Animal</code>, <code>Cat</code> and <code>Dog</code> to describe inheritance; and <code>Student</code> or <code>Account</code> as examples to illustrate data storage concepts. Somewhere down the line, example code went through a transition. Now, sample code looks like this:</p>
<pre><code>Band ledzep = new Band();
ledzep.type = BandType.ROCK;
//...
performances.add(ledZep);
</code></pre>
<p>Or, as one of my favorite books used to describe singleton pattern using <code>enum</code>s in Java:
<code>Elvis.INSTANCE.leaveTheBuilding();</code></p>
<p>Now that was cool ... for someone who has heard of Elvis. But, this may sound impossible, but there are developers who have never heard of Elvis. They will miss the point, for sure.</p>
<p>What I'm trying to say here is: Sample code should try to put across the point without being gimmicky. The gimmicks might be picked up by some, but will definitely be lost on some others.<br />
</p>
<h3>Program Elements:</h3>
<p>So, you are designing an API. You try to follow all the best practices. You start thinking of a name for that particular class. You want the class name to be as descriptive as possible. Then you end up with this:</p>
<p><code>public abstract class ImmutableMediationDelegatingStrategyPrefabricator</code></p>
<p>or a method like this:</p>
<p><code>public void incrementalAddThenComputeAverageAndPersist()</code></p>
<p>A potential developer takes one look at your API, and is likely to never return to your site again.</p>
<p>Okay, those were extreme examples. But not all that distant from the truth. The gist here is that the name of your API should help the developer understand its concise objective. If the developer has to reach for the dictionary to understand what the hell the class name means, you've got it wrong.</p>
<h3>Libraries:</h3>
<p>Ditto with the name of the library itself, where we see the other extreme. Its good to be creative and think of cool names; but there are plenty of examples of devs who overdid it, and ended up with names that make sense only to a small percentage of the target audience. This holds even if the catchy name is somehow related to the functionality the library provides (which is in itself a rarity).</p>
<p>Would you make an effort to understand my library if I named it <code>kumbh-ka-mela</code>? Or <code>Kodachadri</code>?</p>
<h3>The Bottom Line:</h3>
<p>It is simple really. As a developer, every aspect of your product is carefully designed keeping the end user in mind. The same consideration should be extended to other developers who will be using your development tool. Right from program concepts to developer documentation, one must strive to make the artifacts as inclusive as possible.</p>
<p>After all, more the developers use my development tool, the more I benefit. Right?<br />
</p>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-15002804081198360832012-05-07T09:45:00.000+05:302012-05-07T09:45:53.173+05:30Code. On the Move<div dir="ltr" style="text-align: left;" trbidi="on">
<style type="text/css">
p, li { white-space: pre-wrap; }
</style>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
<h3>
... a.k.a "How I was made to eat the humble pie".</h3>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
Two years back, when tablet computers were re-born, I was super-excited. I thought that finally the PC can be dispensed with. However this joy was short-lived as I soon realized that tablets were primarily data-<em>consumption</em> devices; and data <em>creation</em> is pretty difficult on them.<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
That, and the fact that there was nothing in there for a developer. I mean, how can you cram Eclipse on to that small screen, right?<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
That is why when I saw <a href="http://stackoverflow.com/questions/3586174/is-it-possible-to-develop-for-android-on-android">this question on StackOverflow</a>, I laughed and laughed. I showed it to a friend, and we both laughed. The title of the question was:<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
<blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
Is it possible to develop for Android on Android?<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
</blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
Yeah, right. Hahahaha. We scoffed and ridiculed right until we saw one of the answers, which pointed us to <a href="https://play.google.com/store/apps/details?id=com.aide.ui&hl=en">AIDE</a>. And then, we stopped laughing.<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
AIDE is an actual complete IDE which you can use to develop Android apps <strong><em>on an Android device</em></strong>. Make sure you read that again. Now, when I first saw it, I was mighty skeptical. I mean, C'mon now! No kidding.<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
I decided to do a critical analysis of this little app claiming to be an IDE, and found every one of my questions being answered by the features list. The conversation went like this:<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
<blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
What use is an IDE that doesn't provide syntax highlighting, eh?<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
</blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
But AIDE does have syntax highlighting. In Java, in XML, and everywhere you would expect.<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
<blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
But surely, it doesn't provide completion suggestions. Aha!<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
</blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
Sure does. You can configure the number of characters to type before code completion kicks in.<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
<blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
But then I'm sure its impossible to <strong><em>compile</em></strong> the Java code! (Triumphant expression)<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
</blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
Not at all. AIDE comes with a Java compiler.<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
<blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
How about pointing out errors as you type?<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
</blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
Yup. AIDE has that; plus suggestion for correction.<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
<blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
Ok. You can compile Java, but how will you compile the resource files; and how will you generate the APK? (Nail-in-the-coffin)<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
</blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
Simple. AIDE uses the open source implementations of dx and other tools from AOSP. And yes, AIDE generates a complete, signed APK.<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
<blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
(By this time, I'm feeling the cockiness drain out) Ok, that's cool; but this is still a useless app. Think about it - how many people are really going to code an entire app on an Android phone?<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
</blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
That's where GitHub and DropBox integration come in. AIDE will probably be used more as an edit-on-the-go rather than code-from-scratch-on-the-go environment. So, write your code on your traditional PC. Upload it to GitHub or Dropbox - and you're good to go.<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
<blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
But, aren't these project structures incompatible?<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
</blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
Nope. AIDE projects are fully compatible with Eclipse projects.<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
<blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
Size?<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
</blockquote>
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
10 MB at last count.<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
By this time, I had installed the app on a Samsung Galaxy S Captivate and given it a good spin. The verdict was unanimous: AIDE is a brilliant app. I was forced to eat the humble pie (and I was glad to do it!).<br />
<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
Hats off to AIDE.They have come out with an app that I never imagined would be possible. Hail Innovation!<br />
</div>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-91889870355321118442012-04-05T08:22:00.000+05:302012-04-05T10:51:00.428+05:30Mark It Down<div dir="ltr" style="text-align: left;" trbidi="on">
<h4 style="text-align: justify;">
<u>Then</u>:</h4>
<div style="text-align: justify;">
My traditional workflow for writing a blog post used to be this:</div>
<ol style="text-align: justify;">
<li>Type it out offline in a Word Processor (MS Word, Open Office, Lotus Symphony, Libre Office - what have you).</li>
<li>When the post is ready, first copy-paste it into Google Docs.</li>
<li>Then, create a new post in Blogger, and paste in the contents.</li>
<li>Often, several formatting "adjustments" would be needed (let me not even go into the details of these adjustments!)</li>
<li>Finally, publish the post.</li>
</ol>
<div style="text-align: justify;">
The idea was to have a copy of the document outside of blogger (in case I decide to switch hosting platforms etc). The Google Docs step was in order to have a cloud copy of the "copy outside Blogger". Yes, go ahead. Throw back your head and laugh out loud at the stupidity of it all. I deserve it :-)</div>
<div style="text-align: justify;">
<br />
But, let's face it: Word Processors are not meant for producing content for the web. </div>
<ul style="text-align: justify;">
<li>Copy-pasting from a Word Processor document into any post editor invariably messes up the formatting. </li>
<li>Then there's the issue of things like line-spacing and "Justify" settings in word processors - these do not translate to HTML in a standard way. </li>
<li>Finally, stuff like quoting passages of text; or inserting in-line pre-formatted code is mighty difficult to get right while using a combination of Word Processors and post editors.<br />
</li>
</ul>
<h4 style="text-align: justify;">
</h4>
<h4 style="text-align: justify;">
<u>Now</u>:</h4>
<div style="text-align: justify;">
In order to get past all these problems, I have now turned to <a href="http://en.wikipedia.org/wiki/Markdown">Markdown syntax</a>. As you can see, markdown is a simple syntax for formatting web content (headers, paras, bullet points, quotes, code etc). The advantages of Markdown for me are:</div>
<ul style="text-align: justify;">
<li>Simple, familiar(?) syntax. (If you have used StackOverflow, you have already used Markdown)</li>
<li>Produces HTML as output.</li>
<li>Implemented in a standard way across Markdown Editors.</li>
<li>Especially convenient for use cases like this technical blog that you are reading, where I will need to include lots of inline code snippets and the like.</li>
</ul>
<div style="text-align: justify;">
<br />
My new workflow for publishing a post is:</div>
<ol style="text-align: justify;">
<li>Write the post in a Markdown Editor. I use <a href="http://sourceforge.net/p/retext/home/ReText/">ReText</a>, but there are dozens of them out there, for every platform, and even web-based ones.</li>
<li>Export it as HTML.</li>
<li>Make minor changes in the HTML if required. For example, I use <a href="http://code.google.com/p/google-code-prettify/">google code prettify</a> for syntax highlighting. This requires HTML <code>code</code> elements to have specific CSS styles associated with them.</li>
<li>Copy the final HTML into the <b>HTML editor</b> of Blogger.</li>
<li>Publish it (actually, I <b>schedule</b> my posts rather than publish them right away - because I wrote several posts at a time and then space them out. But that's a different topic).</li>
</ol>
<div style="text-align: justify;">
<br />
I suppose some of these steps can further be eliminated - for example:</div>
<ul style="text-align: justify;">
<li>Some blogging platforms already allow Markdown directly in their post editors. </li>
<li>If and when Blogger allows Markdown directly in the post editor, I can skip the HTML exporting part.</li>
<li>That part about adding specific CSS classes to the <code>code</code> elements - that can probably be automated with Javascript.</li>
</ul>
<div style="text-align: justify;">
<br />
What we have at the end of the day is a simple, predictable and no-fuss workflow for writing blog posts which are not only well-formatted, but are also interleaved with quotes and code blocks; all this without breaking HTML.</div>
<h4 style="text-align: justify;">
</h4>
<h4 style="text-align: justify;">
<u>Customize</u>:</h4>
<div style="text-align: justify;">
You might have observed that Markdown (or rather the HTML output of Markdown) only defines the <i>structure</i> of the content, and not the <i>style</i>. What this means is that you can customize the look of the HTML procuded by Markdown, by suppying appropriate CSS styles. Note that this is consistent with the best practices of web development: </div>
<div style="text-align: justify;">
<blockquote>
Separate structure from presentation.</blockquote>
</div>
<div style="text-align: justify;">
This is exactly what Markdown does: Defines the semantic structure, but leaves the presentation to the CSS.</div>
<h4 style="text-align: justify;">
</h4>
<h4 style="text-align: justify;">
<u>Cons</u>:</h4>
<div style="text-align: justify;">
I have been a big fan of 1.5 line spacing and the "Justify" feature of Word Processors. It looks like these formatting features are unavailable in Markdown (probably because they do not translate to HTML in a standard way). But on second thoughts, this probably is a good thing - since including line spacing and Justification would pollute the structure with presentation!</div>
<h4 style="text-align: justify;">
</h4>
<h4 style="text-align: justify;">
<u>Conclusion</u>:</h4>
<div style="text-align: justify;">
I've adopted Markdown for not only my blogging needs, but for much more (writing documentation, for example). It works pretty well, is hassle-free and is simple. Do let me know what tools you use and the workflow you follow for content creation and publishing.</div>
</div>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-29129386895697996092012-03-27T10:00:00.000+05:302012-05-14T09:19:12.474+05:30Internationalization, In Spirit - Part 2: Cultural Sensitivity<p>In <a href="http://curioustechizen.blogspot.in/2012/03/internationalization-in-spirit.html">Part 1</a> of this series, I touched upon how software should target a wider audience by being easy to consume by people around the planet. I used the term "internationalization" in that post, but I really meant a combination of internationalization (i18n) and localization (l10n). In this post, and the rest of this series, I use these terms interchangeably. I realize technically speaking they are different but I really think both these terms should for the most part, be mentioned in the same breath.</p>
<hr />
<p>In my opinion, the biggest missing piece in the whole global software story is cultural sensitivity. When designing, developing and distributing software, we often overlook the fact that the user of this software could be from a culture that is diametrically opposite to our own. Let me refrain from taking names; but for a moment take a look at the list of software installed on your computer or phone and you will know what I mean. <strong><em>How many of the concepts presented in these software are you really familiar with?</em></strong></p>
<p>I will draw up a list of hypothetical examples here to drive home my point:</p>
<ul>
<li>Imagine a software tool that has one particular “fun” feature and names it Aloha. Now an American might immediately associate Aloha with Hawaii and therefore with fun, but what difference does it make to a person on the other side of the globe?</li>
<li>Imagine a role playing game in which one particular level involves the player attending high school prom. If your game targets a global audience, chances are most of your users have never been to prom; and those who do not have Hollywood influence don’t even know what a prom is.</li>
<li>Suppose you have a game where you grade your players according to high scores. What do you think would be the consequence of grading them as “Sachin”, “Viru”, and “Dhoni”? I’m sure people from non-cricketing nations reading this post won’t even get the reference.</li>
</ul>
<p>One can go on and on pulling out examples, but you see where this is heading, don’t you? The underline here is this: <strong><em>In an attempt to make a product more user-friendly, we tend to link it to things that we see and use every day. Unfortunately, we fail to realize that those very “things” might be totally unheard of</em></strong> in markets where our products are targeted.</p>
<hr />
<p>I don’t believe there is an easy solution though. None of the options seem to be good in their own right.</p>
<ul>
<li>It is highly improbable that one will find one concept that fits all cultures.</li>
<li>The costs associated with adapting the very concepts the product is based on, to various cultures, is sure be prohibitive.</li>
<li>Keeping things culture-neutral is likely to make the product dry and boring - a kill-joy for sure.</li>
</ul>
<p>In the end it is a matter of finding the balance that works for you. But before arriving at that formula, it is worth considering the cultural aspect in some detail so as to be in the good books of all end-users!</p>
<hr />
<p>In the next installment of this series, we will look at how the software development community could be more inclusive of developers around the world.</p>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-25695066640826724572012-03-19T11:00:00.000+05:302013-01-10T12:07:54.241+05:30Override and Debug<div dir="ltr" style="text-align: left;" trbidi="on">
What would we ever do without a debugger eh? In the Java world, it’s JPDA. Integrated with your favourite IDE, it makes debugging your source code a breeze. Just set a breakpoint someplace in your code, and then step through.<br />
<br />
But wait. What happens when you step into code that’s outside your project? What if you step into a method that’s from a library, or from the core platform itself? You end up seeing something illegible: some bytecode, or just a “Source not found” message (if you are using Eclipse that is). Go ahead: try it out:<br />
<ul>
<li>Write a bare minimum <code>“Hello World!”</code> application.</li>
<li>Put a breakpoint at the line where you print the message to <code>System.out</code>.</li>
<li>Now debug your application and step into the <code>System.out.println</code> method.</li>
</ul>
What do you see?<br />
<h3>
</h3>
<h3>
Solutions?</h3>
The best solution, of course, is to attach the source code, if available. Unfortunately, most of the time the source code is not available, and even if it is, “attaching” it is not the easiest thing to do. If you have worked with Android, you know what I mean.<br />
<br />
What’s the second-best solution? Use the <b><i>override-debug technique</i></b>. Although this technique does have its limitations (as we will discuss later in this article), it does turn out to be useful in a large number of use-cases. The technique is as follows:<br />
<ul>
<li>Choose the library method that you wish to debug. Note that you might not care about the method that you call directly from your code. Instead, you might be interested in a method, say, four levels deep in the call stack.</li>
<li>Extend the class which contains this method, and override it.</li>
<li>Simply call the <code>super</code> method in the overriden implementation.</li>
<li>Finally, while debugging, put a breakpoint in the brand new one-liner method that you just implemented.</li>
</ul>
<br />
Congrats! You’ve just managed to see what’s happening four levels deep in the call hierarchy; without even having the source code.<br />
<h3>
</h3>
<h3>
Show me some Code!:</h3>
Much of that did not make sense, did it? Probably because it was all text and no code? Fear not, for the code example is here!<br />
<br />
I use an (admittedly contrived) example to demonstrate this technique. I have a <code>Laundry</code> class and a <code>doLaundry()</code> method within it which takes a bunch of clothes as arguments. This method<br />
<ul>
<li>First invokes the <code>WashingMachine</code> object to wash and rinse the clothes.</li>
<li>Then it calls upon a <code>Dryer</code> to spin them.</li>
<li>Finally, it hangs out the clothes to dry on a <code>Clothesline</code>. </li>
</ul>
All of this is within a library for which you don't have the source.The objective is to debug what is happening when the control reaches the <code>Clothesline.hang()</code> method.<br />
<br />
<pre class="prettyprint"><code>public class LaundryRunner {
private static Laundry laundry = new Laundry();
public static void main(String[] args) {
/*
* Initialize the clothes for laundry
*/
List clothes = new ArrayList(3);
clothes.add(new ClothingItem("shirt", "white", "stained"));
clothes.add(new ClothingItem("jeans", "blue", "dirty"));
clothes.add(new ClothingItem("t-shirt", "red", "dirty"));
/*
* Objective: To try to debug whats going on inside.
* For example, what happens by the time the clothes reach the clothesline?
*/
laundry.doLaundry(clothes);
}
}</code></pre>
<br/>
You could put a breakpoint at the <code>doLaundry()</code> invocation, but since you don't have the source attached, you draw a blank.<br />
<br />
The solution is to extend the <code>Clothesline</code> class as follows:<br />
<br />
<pre class="prettyprint"><code>public class CustomClothesline extends Clothesline {
@Override
public void hang(List clothes) {
System.out.println("Debugging in Custom Clothesline");
System.out.println("Status of clothes given to me:");
for(ClothingItem item: clothes){
System.out.println(item.getStatus());
}
super.hang(clothes);
}
}</code></pre>
<br/>
And then, instruct the <code>Laundry</code> class to use your custom <code>Clothesline</code> instead of the default one.<br />
<br />
<pre class="prettyprint"><code>laundry.setLine(new CustomClothesline());
laundry.doLaundry(clothes);</code></pre>
<br/>
This entire project and source code is available here. I have included the dependent project as a JAR library, but it is also available as a separate project in case you want to look at it.<br />
<br />
Ok that was just an example code. To see the override-debug technique in the real world, see <a href="http://code.google.com/p/android-drawable--invalidation-on-orientation-issue/">this project</a> on Google Project Hosting (pay special attention to <code>CustomDrawable.java</code> ). Here, I would ordinarily have used a <code>BitmapDrawable</code> object, but I wanted to know what happens when the <code>onBoundsChanged()</code> method is called. I achieved this by extending <code>BitmapDrawable</code> and overriding the method I was interested in.<br />
<h3>
</h3>
<h3>
Limitations:</h3>
The override debug technique has the following constraints:<br />
<ul>
<li>The class that you want to debug must be extensible. This means it must be declared <code>public</code> and not <code>final</code>.</li>
<li>The method which you want to override must be, well, overridable. This means it must have a visibility of at least <code>protected</code>, and of course it should not be declared <code>final</code>.</li>
</ul>
<h3>
</h3>
<h3>
An aside:</h3>
You’re probably thinking that the above two limitations render this technique more or less useless. After all, as a best practice, developers of libraries and frameworks are unlikely to allow overriding of their classes and methods unless they are explicitly designed to do so (for example life-cycle methods).<br />
<br />
It turns out in practice this is not much of a constraint. Frameworks like Android allow you to extend and override almost anything. The following is a stackoverflow discussion on this topic.<br />
<div class="onlyShowAcceptedAnswer-true" id="stacktack-8091624">
</div>
</div>
<script>prettyPrint()</script>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-11490399210333963322012-03-10T09:38:00.000+05:302012-03-18T10:36:42.616+05:30Internationalization, In Spirit - Part 1<div dir="ltr" style="text-align: left;" trbidi="on">
<style type="text/css">
<!--
@page { margin: 0.79in }
P { margin-bottom: 0.08in }
-->
</style>
<br />
<div align="JUSTIFY" class="western" style="line-height: 150%; margin-bottom: 0in;">
<a href="http://www.blogger.com/blogger.g?blogID=1898571694993659507" name="internal-source-marker_0.7259663810191946"></a>
<br />
<span style="color: black;"><span style="text-decoration: none;"><span style="font-family: Arial;"><span style="font-size: small;"><span style="font-style: normal;"><span style="font-weight: normal;"><span style="background: none repeat scroll 0% 0% transparent;">You’re
watching an amazing program on Discovery. It is about some
mind-boggling natural wonder - say, the Grand Canyon, or the Amazon
.. or something of the sort. You watch (and hear) in awe, as the
narrator unfolds the statistics of the phenomenon. And then, in a bid
to impress upon you how big the structure really is, he says “It is
[insert-some-number] feet long, that’s [insert-some-other-number]
New York city blocks put together”.</span></span></span></span></span></span></span></div>
<div align="JUSTIFY" class="western" style="line-height: 150%;">
<br /></div>
<div align="JUSTIFY" class="western" style="font-style: normal; font-weight: normal; line-height: 150%; margin-bottom: 0in; text-decoration: none;">
<span style="color: black;"><span style="font-family: Arial;"><span style="font-size: small;"><span style="background: none repeat scroll 0% 0% transparent;">And
you go, “How in the world am I supposed to know how big a block
is?”. You feel anger and disappointment rising up in equal amounts.
You start trying to figure out that calculation. You miss the next
five minutes of the program. Before you know it, you’ve lost track,
and interest.</span></span></span></span></div>
<div align="JUSTIFY" class="western" style="line-height: 150%;">
<br /></div>
<div align="CENTER" class="western" style="font-style: normal; font-weight: normal; line-height: 150%; margin-bottom: 0in; text-decoration: none;">
<span style="color: black;"><span style="font-family: Arial;"><span style="font-size: small;"><span style="background: none repeat scroll 0% 0% transparent;">****************</span></span></span></span></div>
<div align="JUSTIFY" class="western" style="line-height: 150%;">
<br /></div>
<div align="JUSTIFY" class="western" style="font-style: normal; font-weight: normal; line-height: 150%; margin-bottom: 0in; text-decoration: none;">
<span style="color: black;"><span style="font-family: Arial;"><span style="font-size: small;"><span style="background: none repeat scroll 0% 0% transparent;">Rewind
to networking class in your college days. You are studying the token
ring algorithm. Your book explains the workings of the algorithm in
detail, but every so often makes a reference to “token system in
public service office counters”. Basically the book assumes that
you are already amply familiar with this token-something-something
system, whatever it is. Forget the book, the algorithm itself makes
this assumption.</span></span></span></span></div>
<div align="JUSTIFY" class="western" style="line-height: 150%;">
<br /></div>
<div align="JUSTIFY" class="western" style="font-style: normal; font-weight: normal; line-height: 150%; margin-bottom: 0in; text-decoration: none;">
<span style="color: black;"><span style="font-family: Arial;"><span style="font-size: small;"><span style="background: none repeat scroll 0% 0% transparent;">Bad
assumption, you say. You come from a country where there is hardly a
concept of a queue, let alone tokens. You have a hard time grasping
the concept. Worse, you begin hating that algorithm!</span></span></span></span></div>
<div align="JUSTIFY" class="western" style="line-height: 150%;">
<br /></div>
<div align="CENTER" class="western" style="font-style: normal; font-weight: normal; line-height: 150%; margin-bottom: 0in; text-decoration: none;">
<span style="color: black;"><span style="font-family: Arial;"><span style="font-size: small;"><span style="background: none repeat scroll 0% 0% transparent;">****************</span></span></span></span></div>
<div align="JUSTIFY" class="western" style="line-height: 150%;">
<br /></div>
<div align="JUSTIFY" class="western" style="font-style: normal; font-weight: normal; line-height: 150%; margin-bottom: 0in; text-decoration: none;">
<span style="color: black;"><span style="font-family: Arial;"><span style="font-size: small;"><span style="background: none repeat scroll 0% 0% transparent;">Okay.
I admit that was exaggerated. But the fact remains.</span></span></span></span></div>
<div align="JUSTIFY" class="western" style="line-height: 150%;">
<br /></div>
<div align="JUSTIFY" class="western" style="line-height: 150%; margin-bottom: 0in;">
<span style="color: black;"><span style="text-decoration: none;"><span style="font-family: Arial;"><span style="font-size: small;"><span style="font-style: normal;"><span style="font-weight: normal;"><span style="background: none repeat scroll 0% 0% transparent;">Internationalization
has gone from being a best practice to becoming an absolute
requirement in most software applications.</span></span></span></span></span></span></span><span style="color: black;"><span style="text-decoration: none;"><span style="background: none repeat scroll 0% 0% transparent;">
</span></span></span><span style="color: black;"><span style="text-decoration: none;"><span style="font-family: Arial;"><span style="font-size: small;"><i><b><span style="background: none repeat scroll 0% 0% transparent;">How
widely a software is adopted is directly tied to how usable it is by
people all over the planet</span></b></i></span></span></span></span><span style="color: black;"><span style="text-decoration: none;"><span style="font-family: Arial;"><span style="font-size: small;"><span style="font-style: normal;"><span style="font-weight: normal;"><span style="background: none repeat scroll 0% 0% transparent;">.
</span></span></span></span></span></span></span>
</div>
<div align="JUSTIFY" class="western" style="line-height: 150%;">
<br /></div>
<div align="JUSTIFY" class="western" style="font-style: normal; font-weight: normal; line-height: 150%; margin-bottom: 0in; text-decoration: none;">
<span style="color: black;"><span style="font-family: Arial;"><span style="font-size: small;"><span style="background: none repeat scroll 0% 0% transparent;">These
days it is pretty standard for any application development framework
(language/platform/stack) to provide techniques for developers to
easily internationalize their applications. Display messages, units,
currencies are all externalized from the code itself. Heck,
developers don’t even write the display messages - that task is
outsourced to translators.</span></span></span></span></div>
<div align="JUSTIFY" class="western" style="line-height: 150%;">
<br /></div>
<div align="JUSTIFY" class="western" style="font-style: normal; font-weight: normal; line-height: 150%; margin-bottom: 0in; text-decoration: none;">
<span style="color: black;"><span style="font-family: Arial;"><span style="font-size: small;"><span style="background: none repeat scroll 0% 0% transparent;">But,
is this sufficient? Would people the world over be happy if their web
app displayed messages in their language, Rupees instead of Dollars,
and kilometres in place of miles? I think not. In this series of
posts, I will present my argument on why I think the software world
is still a far cry from being truly global.</span></span></span></span></div>
<div align="JUSTIFY" class="western" style="line-height: 150%;">
<br />
<br /></div>
<div align="JUSTIFY" class="western" style="font-style: normal; font-weight: normal; line-height: 150%; margin-bottom: 0in; text-decoration: none;">
<span style="color: black;"><span style="font-family: Arial;"><span style="font-size: small;"><span style="background: none repeat scroll 0% 0% transparent;">Stay
tuned for Part 2 of this series, which will talk about cultural
sensitivity.</span></span></span></span></div>
<div align="JUSTIFY" class="western" style="line-height: 150%;">
<br />
<br />
<br /></div>
</div>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.comtag:blogger.com,1999:blog-1898571694993659507.post-85107262477967301742012-02-04T10:08:00.001+05:302012-03-18T10:35:58.426+05:30Testing the template<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
This is a test post. I am using it to test the formatting and the template using prettify.js. Let me post some code and see how it works out.<br />
<br /></div>
<pre class="prettyprint">public static void main(String [] args){
System.out.println("Hello World!");
}
</pre>
</div>Kiranhttp://www.blogger.com/profile/11953320626421863532noreply@blogger.com