Tuesday, December 18, 2012

Code Smells: Calling Life-Cycle Methods of Program Components Explicitly

Here is some code I see that sets off alarm bells clanging in my head:

Explicitly calling life-cycle methods of components that are outside your control.

Since that sounds oh-so-generic, let me illustrate by way of example.

Assume you are writing a Servlet 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:

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
    }
}

I would never do this though. This is because doGet, doPost and the other doXXX methods are life-cycle methods of the Servlet. 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 doGet returns, and that action could be different from what is done once a doPost returns.

It is really a simple matter of extracting the "common functionality" between such life cycle methods into a method and calling that method.

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
    }
}

What if the life cycle methods are in an Interface?

One opinion that came up in a discussion was that it is safe to call other life-cycle methods if they are in an interface as opposed to a class. Note that the above code sample extends javax.servlet.http.HttpServlet which is an abstract class as opposed to the base javax.servlet.Servlet which is an interface. This has come up specially while discussing callbacks.

I disagree with this opinion since it assumes that any book-keeping has to be performed by the same (possibly abstract) class that denotes the life-cycle component. This is not true. Take an imaginary UI toolkit for example, which has a Pane as a UI element. Now, assume an interface for handling interaction callbacks:

interface InteractionListener{
    public void onClick();
    public void onRightClick();
    public void onLongClick();
    public void onDoubleClick();
}

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:

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
        }
});

This is still wrong. Yes- InteractionListener 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 after your onXXXClick() methods return. The solution, again is exactly the same as before: extract the common code into a method which you then invoke from both onLongClick() and onRightClick().

Conclusion

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.

A few other instances where I have seen this sort of code:

  • Android's SqliteOpenHelper. In the onUpgrade() 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:

    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.
        }
    }
    

    The right way to do this would be:

    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.
        }
    }
    

I will re-visit this post and add more instances as and when I come across them.

Monday, December 3, 2012

Android: "Application level" Pause and Resume

Update

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 android-app-pause on github

Introduction

I have often come across questions on StackOverflow and the android-developers google group about an Application-level onPause() and onResume(). 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 onPause()?

After all, an Android app consists of multiple components, several of which might be in the background. There could be Services, Threads, BroadcastReceivers, scheduled Alarms. How do these figure in a "paused" app? Well, here's my definition of an app being paused for the purposes of this post:

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, none of the Activities that belong to the app are visible to the user.

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.

Similarly, an app is considered to be resumed when at least one Activity from the app is visible to the user.

This is the point at which the app can re-establish HTTP communication, re-schedule alarms and the like.

TL;DR

I got this idea from this answer that I gave on stackoverflow. The basis of this approach is that when an Activity starts another, both of them undergo lifecycle changes in a predictable fashion. The series of steps to follow to achieve the app-level pause and resume functionality is as follows:

  1. Create a bound Service (let's call this AppActiveService).
  2. In the onStart() of every Activity of your app, bind to AppActiveService.
  3. In the onStop() of every Activity of your app, unbind from AppActiveService.
  4. The onDestroy() method of AppActiveService represents the point when your app is "pausing"; while the onBind() 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 AppActiveService's onDestroy() method.

To make things even simpler, you can put all the code above in a BaseActivity for your application and have all your other Activities inherit from this BaseActivity.

If you follow the steps above, the AppActiveService will have at least one Activity bound to it as long as your app is visible to the user. When this condition is false, no Activity is bound to the Service, at which point its onDestroy() is called.

Do note that we are using onStop() and not onPause() to un-bind from the Service. If you were to use onPause(), then there would be zero components bound to AppActiveService even as you are switching from one Activity to the other within your own app.

Gotchas

One gotcha in this approach is: What happens if your app "starts another app" using an Intent? No Activity 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.

Conclusion

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?

Saturday, September 29, 2012

Google Play Services, and Why We Still Need AccountManager

Introduction

Recently, Google has started rolling out the widely awaited Google Play Services, announced during Google I/O 2012. One of the major pieces of Google Play Services is the GoogleAuthUtil. The principal problem that this component solves is OAuth. Up until now, writing an Android app that requires OAuth has been complex and non-standard.

  • Complex, because you need perform the whole OAuth dance behind the scenes (not specific to Android, mind you).
  • 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 raw oauth scope strings in some OAuth confirmation screens rather than a user-friendly description of the scope.

The AccountManager framework 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 GoogleAuthUtil, and the AccountPicker were previewed at IO2012, I was jumping in excitement. If you want your app to use OAuth with Google, then GoogleAuthUtil makes life a whole lot simpler.

Caveat

But, therein lies the caveat. It only applies to Google Accounts. 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.

What is really required is for more identity providers to leverage the AccountManager framework in Android. Admittedly, that is not so straightforward. Not only does it involve writing an AccountAuthenticator, there are some pieces specific to identity provider and there is no go-to place to publish the documentation for these provider-specific pieces.

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 accountType for Twitter is? How do I know the valid values for features parameter for Twitter?

But the problem doesn't stop there. Apparently, some third-party services require you to use their OAuth API to sign the user in. 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.

Solution (?)

I really think third party identity providers (at least the big ones) should make an effort to leverage AccountManager framework of Android. This may be additional work - but just look at the size of the customer base they are targetting. With the new AccountPicker, 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:

An end user should never be forced to enter the credentials for an account that is already present in the "Accounts" settings screen

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.

Conclusion

In a nutshell:

  • Google Play Services (in particular AccountPicker) = Good - for Google Accounts.
  • Third party identity providers and OAuth providers: WebView = Bad. Please use AccountManager and AbstractAccountAuthenticator.

Thursday, July 26, 2012

That's NOT Fragmentation; But then What Is?


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 not such a bad thing. But, this fragmentation is making my life as a developer that much more difficult. That's the bad thing.

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 NOT".

Oh! There's 4-inch phones, 7-inch tabs and 10-inch tabs? Damn! Fragmentation!

OR

Urghh! So many different device manufacturers? So many thousands of device models? They won't all have the same hardware and capabilities :-( Damn! Fragmentation!

Try This

What? Every release of Android has its own theme and look&feel? Damn! Fragmentation!

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.

  • The amazing resources framework 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.
  • 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.
  • 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.

All the above rants, can then be attributed to developers not knowing the framework and the tools properly. These have nothing to do with fragmentation.


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.

RTSP Streaming:

Getting a simple RTSP video stream to play on even the more popular devices using Android's MediaPlayer 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.

Now, That's fragmentation.

Rapid Deprecations:

UI and design patterns that were previously suggested by the Android team 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 ActionBar, and the AsyncTask punishment.

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 natively is just 13%.

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 Android Compatibility Library, ActionBar Sherlock 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 and is truly well-behaved on even 75% of the installed base, you have to roll your sleeves and get your hands dirty.

Now, That's fragmentation.

Very Basic Changes in the Framework:

Since HoneyComb (Android 3.0), the dedicated hardware "Menu" key has been dumped in Android, to be replaced with an overflow menu in the ActionBar. This seems like a simple problem, until you come across problems like this one.

You can't even be confident that your erstwhile awesome app will display that menu properly across all devices.

Now, That's fragmentation.

The way you are supposed to use the Back Button has been changed and made all the more confusing 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.

To balance the way the back button is supposed to work in various versions of the platform, with the way you want it to work might take quite a lot of effort (especially since the compatibility API's don't really do the job here).

Now, That's fragmentation.

Patent-induced inconsistencies:

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).

Pretty basic stuff, right? Well, this may no longer be the case. As a result of a patent issues, at least one manufacturer has modified this behavior. 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?

Now, That's fragmentation.


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:

  • The AsyncTask, ActionBar and Menu key problems I mentioned will probably not be a problem once we have more devices running ICS and above.
  • 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 new guidelines consistently. I also don't expect Google to make any more drastic changes in these areas in the near future.
  • Even the MediaPlayer framework inconsistencies are bound to shrink with more adoption of the newer platform releases.
  • 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 GOOD!

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?


Conclusion:

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.

Once this pie-chart 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.

Wednesday, June 13, 2012

Internationalization in Spirit: Part 3 - Developers

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 Part 1 and Part 2 to get some context.

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.

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.

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

  • the complicated language in use in developer documentation
  • the “heavy” words used to name program elements (classes, functions, variables .. )
  • 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.

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.

Developer Documentation:

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.

Consider the following method doc:

String bestMatch(String text)

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, null otherwise.

Yes that was correct. But how easy was it to comprehend? Now, consider the same method doc re-written as follows:

String bestMatch(String text)

  1. Scans database of known keywords , attempting to match the supplied text with the keyword.

  2. If the database is empty, attempts a match on content and description fields.

In both cases, this method returns the best match String if found, null otherwise.

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.

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!

Samples:

Back in college, we mostly used Animal, Cat and Dog to describe inheritance; and Student or Account as examples to illustrate data storage concepts. Somewhere down the line, example code went through a transition. Now, sample code looks like this:

Band ledzep = new Band();
ledzep.type = BandType.ROCK;
//...

performances.add(ledZep);

Or, as one of my favorite books used to describe singleton pattern using enums in Java: Elvis.INSTANCE.leaveTheBuilding();

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.

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.

Program Elements:

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:

public abstract class ImmutableMediationDelegatingStrategyPrefabricator

or a method like this:

public void incrementalAddThenComputeAverageAndPersist()

A potential developer takes one look at your API, and is likely to never return to your site again.

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.

Libraries:

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).

Would you make an effort to understand my library if I named it kumbh-ka-mela? Or Kodachadri?

The Bottom Line:

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.

After all, more the developers use my development tool, the more I benefit. Right?

Monday, May 7, 2012

Code. On the Move


... a.k.a "How I was made to eat the humble pie".


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-consumption devices; and data creation is pretty difficult on them.

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?

That is why when I saw this question on StackOverflow, I laughed and laughed. I showed it to a friend, and we both laughed. The title of the question was:


Is it possible to develop for Android on Android?


Yeah, right. Hahahaha. We scoffed and ridiculed right until we saw one of the answers, which pointed us to AIDE. And then, we stopped laughing.

AIDE is an actual complete IDE which you can use to develop Android apps on an Android device. Make sure you read that again. Now, when I first saw it, I was mighty skeptical. I mean, C'mon now! No kidding.

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:


What use is an IDE that doesn't provide syntax highlighting, eh?


But AIDE does have syntax highlighting. In Java, in XML, and everywhere you would expect.


But surely, it doesn't provide completion suggestions. Aha!


Sure does. You can configure the number of characters to type before code completion kicks in.


But then I'm sure its impossible to compile the Java code! (Triumphant expression)


Not at all. AIDE comes with a Java compiler.


How about pointing out errors as you type?


Yup. AIDE has that; plus suggestion for correction.


Ok. You can compile Java, but how will you compile the resource files; and how will you generate the APK? (Nail-in-the-coffin)


Simple. AIDE uses the open source implementations of dx and other tools from AOSP. And yes, AIDE generates a complete, signed APK.


(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?


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.


But, aren't these project structures incompatible?


Nope. AIDE projects are fully compatible with Eclipse projects.


Size?


10 MB at last count.

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!).

Hats off to AIDE.They have come out with an app that I never imagined would be possible. Hail Innovation!

Thursday, April 5, 2012

Mark It Down

Then:

My traditional workflow for writing a blog post used to be this:
  1. Type it out offline in a Word Processor (MS Word, Open Office, Lotus Symphony, Libre Office - what have you).
  2. When the post is ready, first copy-paste it into Google Docs.
  3. Then, create a new post in Blogger, and paste in the contents.
  4. Often, several formatting "adjustments" would be needed (let me not even go into the details of these adjustments!)
  5. Finally, publish the post.
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 :-)

But, let's face it: Word Processors are not meant for producing content for the web.
  • Copy-pasting from a Word Processor document into any post editor invariably messes up the formatting.
  • 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.
  • 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.

 

Now:

In order to get past all these problems, I have now turned to Markdown syntax. 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:
  • Simple, familiar(?) syntax. (If you have used StackOverflow, you have already used Markdown)
  • Produces HTML as output.
  • Implemented in a standard way across Markdown Editors.
  • 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.

My new workflow for publishing a post is:
  1. Write the post in a Markdown Editor. I use ReText, but there are dozens of them out there, for every platform, and even web-based ones.
  2. Export it as HTML.
  3. Make minor changes in the HTML if required. For example, I use google code prettify for syntax highlighting. This requires HTML code elements to have specific CSS styles associated with them.
  4. Copy the final HTML into the HTML editor of Blogger.
  5. Publish it (actually, I schedule 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).

I suppose some of these steps can further be eliminated - for example:
  • Some blogging platforms already allow Markdown directly in their post editors.
  • If and when Blogger allows Markdown directly in the post editor, I can skip the HTML exporting part.
  • That part about adding specific CSS classes to the code elements - that can probably be automated with Javascript.

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.

 

Customize:

You might have observed that Markdown (or rather the HTML output of Markdown) only defines the structure of the content, and not the style. 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:
Separate structure from presentation.
This is exactly what Markdown does: Defines the semantic structure, but leaves the presentation to the CSS.

 

Cons:

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!

 

Conclusion:

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.

Tuesday, March 27, 2012

Internationalization, In Spirit - Part 2: Cultural Sensitivity

In Part 1 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.


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. How many of the concepts presented in these software are you really familiar with?

I will draw up a list of hypothetical examples here to drive home my point:

  • 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?
  • 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.
  • 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.

One can go on and on pulling out examples, but you see where this is heading, don’t you? The underline here is this: 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 in markets where our products are targeted.


I don’t believe there is an easy solution though. None of the options seem to be good in their own right.

  • It is highly improbable that one will find one concept that fits all cultures.
  • The costs associated with adapting the very concepts the product is based on, to various cultures, is sure be prohibitive.
  • Keeping things culture-neutral is likely to make the product dry and boring - a kill-joy for sure.

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!


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.

Monday, March 19, 2012

Override and Debug

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.

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:
  • Write a bare minimum “Hello World!” application.
  • Put a breakpoint at the line where you print the message to System.out.
  • Now debug your application and step into the System.out.println method.
What do you see?

 

Solutions?

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.

What’s the second-best solution? Use the override-debug technique. 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:
  • 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.
  • Extend the class which contains this method, and override it.
  • Simply call the super method in the overriden implementation.
  • Finally, while debugging, put a breakpoint in the brand new one-liner method that you just implemented.

Congrats! You’ve just managed to see what’s happening four levels deep in the call hierarchy; without even having the source code.

 

Show me some Code!:

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!

I use an (admittedly contrived) example to demonstrate this technique. I have a Laundry class and a doLaundry() method within it which takes a bunch of clothes as arguments. This method
  • First invokes the WashingMachine object to wash and rinse the clothes.
  • Then it calls upon a Dryer to spin them.
  • Finally, it hangs out the clothes to dry on a Clothesline.
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 Clothesline.hang() method.

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);
   }
}

You could put a breakpoint at the doLaundry() invocation, but since you don't have the source attached, you draw a blank.

The solution is to extend the Clothesline class as follows:

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);
  }
}

And then, instruct the Laundry class to use your custom Clothesline instead of the default one.

laundry.setLine(new CustomClothesline());
laundry.doLaundry(clothes);

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.

Ok that was just an example code. To see the override-debug technique in the real world, see this project on Google Project Hosting (pay special attention to CustomDrawable.java ). Here, I would ordinarily have used a BitmapDrawable object, but I wanted to know what happens when the onBoundsChanged() method is called. I achieved this by extending BitmapDrawable and overriding the method I was interested in.

 

Limitations:

The override debug technique has the following constraints:
  • The class that you want to debug must be extensible. This means it must be declared public and not final.
  • The method which you want to override must be, well, overridable. This means it must have a visibility of at least protected, and of course it should not be declared final.

 

An aside:

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).

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.

Saturday, March 10, 2012

Internationalization, In Spirit - Part 1



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”.

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.

****************

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.

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!

****************

Okay. I admit that was exaggerated. But the fact remains.

Internationalization has gone from being a best practice to becoming an absolute requirement in most software applications. How widely a software is adopted is directly tied to how usable it is by people all over the planet.

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.

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.


Stay tuned for Part 2 of this series, which will talk about cultural sensitivity.



Saturday, February 4, 2012

Testing the template

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.

public static void main(String [] args){
      System.out.println("Hello World!");
}