Wednesday, March 3, 2010

Android SDK from an iPhone Developer's Perspective

I've already given my opinion on the Nexus One hardware. Now it's time to look at the programming side of things. It's time for my opinion of the Android SDK.

Let me start by stating the obvious, because I know a few people will forget this: I'm about to state my own personal and very subjective opinions about the Android SDK. That opinion may differ from yours, and that's okay. Really. It is. The Earth will continue to spin even if you think I'm 100% wrong.

Let me also put my biases right out front: I don't like Java. I've actually been using Java longer than Objective-C and have actually logged more hours and made more money using Java than I have with Objective-C, but from the moment I read Object-Oriented Programming and the Objective-C Language back in 1997 or 1998, I felt like Java was doing many things wrong. Every step in Java's evolution has reinforced and strengthened that feeling. The approach used in NextSTEP (which evolved into Cocoa and then Cocoa Touch) matches my way of thinking. I believe in the approach. I like the approach and the language so much, in fact, that I took a substantial cut in income to be able to work with it full time. So, based on that, you should be able to see that Android's already got one strike against it from my point of view.

I've been intentionally putting off writing this blog post, however, because I didn't want to do what I've seen a lot of people do with the iPhone SDK and Xcode, which is to write a blog post about how it doesn't work the way I expect it to, and therefore it's bad. Given that I already have quite a bit of experience with the language and IDE and have now had several weeks with the Android SDK, I feel like I can give an opinion that's not just me complaining that it's not what I already know and like, though the fact that it does many things in a way I don't like is certainly a factor in my opinion.

So, after spending a few weeks with Android, what do I think?

It's actually not bad. It's a fairly capable SDK. It has most of what you'd need and, being based on Java, there's an awful lot of code and libraries you can draw upon. The design of the SDK is a little inconsistent (just like the Android user experience, actually). There are parts that are almost as close of a copy of the iPhone SDK are very similar in design and feel to the iPhone, and there are parts that seem downright alien1.

There definitely is a lack of consistency in the design when compared to the iPhone SDK. Different parts of the Android SDK feel like they were written by completely different teams that didn't necessarily communicate or even agree on the best way to do things. There are some small inconsistencies in the iPhone SDK, but there are strong guiding principles and dominant design patterns throughout the iPhone SDK that don't have any counterpart in the Android SDK. The overall effect is that Android is a little chaotic and disjointed, but still competent.

Android also has a difficult task in that it's designed to run on such a broad range of hardware and you can developed on a broad range of operating systems and hardware. Google has actually done quite an admirable job given how much harder the problem is when you don't have limited hardware options, all of which you control.

One of the ways they've dealt with this is in the design of the emulator. You can configure the emulator to simulate different hardware with different features and different screen sizes, and you can have multiple virtual devices setup. This means you can test your app on a "virtual Nexus One", then switch to a new virtual device and test on a "virtual Motorola Droid". Working with the emulator is smooth, but not as smooth of an experience as the iPhone Simulator. For example, when you launch an app in the emulator, the emulator doesn't become the front-most application, and the emulator doesn't unlock automatically. But, the experience is still quite decent, especially in light of the additional challenges presented by it being an open platform.

Running on the device worked well, too. Surprisingly well, in fact. Again, it's not quite as smooth of an experience as running on the iPhone. There were little annoyances, such as when you run a program on the device, the phone doesn't wake up or unlock the way the iPhone does. But, overall, it works pretty well and without the hassle of provisioning profiles or developer certificates.

I found debugging to be somewhat painful on Android, but that may just be that I know GDB so much better than JDB/ADB (the Android Debugging Bridge) and I also know Xcode's debugging features much better than Eclipse's.

Although you don't have to use Eclipse to program for Android, it does seem to be the default choice. At least, it seemed like the choice with the fewest obstacles when I was getting everything setup. Eclipse has really good integration with the Android SDK and tools. Running and debugging on the device or on the emulator are a piece of cake, and there are even tools for pushing data to the running virtual device such as location data.

But I hate Eclipse with a passion. It completely and totally doesn't jive with the way I think or work. I find the UI inscrutable and its performance on the Mac is less than stellar. If I were going to be doing a lot of Android development, I would probably invest some time in finding an alternative IDE with good Android integration, or just work with TextMate and the command-line.

I do feel like I can code any application I need using Android. Making it look nice can be a challenge, and I spend a lot more time referencing documentation than I ever did with the iPhone SDK. Knowing one part of the Android SDK doesn't necessarily give you any clues about how another part works and even being an experienced Java developer doesn't give you that much of an advantage in that respect.

Designing views in the Android SDK is one of the areas that I can say without equivocation is worse than the iPhone in every single respect. Android's approach to creating views has absolutely no redeeming value whatsoever. Designing your interface on the iPhone is easy. It's fun. It's intuitive. On Android, it's fucking hell. It's like working with the evil offspring of GridBagLayout and XML. It's utterly horrid. But, Java has never done UI well and has never made it particularly fun so I can't say I was surprised by this, though it did exceed my expectations by being even worse than I thought humanly possible. The whole process is counter-intuitive and time-consuming, and that's just to make something that functions. It's even more time-consuming and painful to make a UI that doesn't look like ass.

But, that's the only area so far in Android that I've found really horrible. Overall, it's a capable SDK. What it's not, however (at least for me), is fun. It's completely missing any fun factor whatsoever. The SDK doesn't get out of my way when I want to create. It's a constant obstacle. Not a big or insurmountable obstacle, but a constant one. The iPhone SDK, on the other hand, is quite fun. Once I understood its approach to doing things, it became quite easy to forget about the SDK and just create my apps.

I've been trying to figure out exactly what the difference is; what it is that makes one fun for me and the other not, and I think I've got it. The Android SDK generally fails to follow one design principle that Apple does pretty damn well, which is:
Make the stuff you do all the time easy.
As a result, on Android, things you almost never do seem to be just about equally hard and time consuming as those that you do all the time.

Case in point: Because of the relatively small screen size, one of the things you do all the time in mobile apps is switch in new screens of data. On the iPhone, we accomplish that like so:
  1. Create an instance of the view controller class for the view we want to show
  2. Set properties on that view controller to provide it with the data it needs to function
  3. Present the view controller's view by adding it to the view hierarchy, pushing it onto a navigation controller's stack, or presenting it modally, each of which typically requires a single line of code
Now, on Android, it's not quite so straightforward.
  1. Add an entry for the Activity (which is similar to UIViewController, but not exactly the same) to your application's Android Manifest to let Android know the class can be launched
  2. Create an Intent based on the Activity's class
  3. Make sure that any data you want to pass to the other Activity is serializable or in the shape of raw datatypes
  4. Push the information you want to pass to the other Activity as an "extra" to the Intent, serializing those that are objects
  5. Start the Activity
  6. In the Activity class, override onActivityResult and retrieve the extras you need, deserializing those that aren't native datatypes.
  7. In the Activity override the onCreate() method to specify the view to be used (and don't even get me started on designing views in Android...)
In reality, the two lists above don't do justice to the difference in effort. This is a task that becomes second nature for the iPhone developer because it's intuitive, and thankfully so. This is the kind of three or four line chunks of code you begin to write without even thinking about it. On Android, the stuff you need to do to accomplish the same task is scattered throughout your project files and the process is not likely to ever become second nature or easy.

Now, people who love Android will argue that Intents are powerful - more powerful than the iPhone's approach because Intents can be used to let other programs and the OS leverage functionality from your program.

Indeed. Intents are powerful. The problem is that they give you power that you don't need the vast majority of the time in the vast majority of applications. And they do that at the expense of making something you need to do all the time more involved and more complex than it should be (and, therefore, more likely to contain bugs). It's indiscriminate complexity, which is not a virtue. As OpenDoc and CyberDog will gladly attest, seemingly good concepts do not always make for good implementations or user experiences, and the iPhone hasn't suffered much for its lack of a way to share functionality between applications.

To me, much of the Android SDK (pretty much the parts that weren't heavily influenced by the iPhone SDK) seem to be over-engineered. Much of the Android SDK features complexity seemingly for complexity's sake. Fifteen years ago, I would have loved it because I was in my over-engineering macho-programmer phase2 and that complexity and the theoretical power it gave me would have seemed really cool.

Today, it just makes me shake my head and think Google's engineers should stop showing off how smart they think they are and start writing elegant code that's exactly as complex as it needs to be. They should be designing their SDK's architecture with an awareness of the fact that that not all tasks are created equal, and simplicity is, at times, the absolute best choice.

But, despite my feelings about Android's elegance, it absolutely is a decent mobile SDK. There's a lot of functionality in there, and an awful lot of libraries and sample code that you can draw on to avoid re-inventing the wheel in your applications.

I don't see myself ever doing Android work full time. I don't see myself ever actively looking for Android SDK work that's not part and parcel of a larger project that includes an iPhone application. But, bottom line, it's not bad. It is, at times, inelegant, unnecessarily complex, and convoluted, but it's young and it still has the potential to grow into a great SDK.

Will Android take off? Probably. There are a lot of Android phones coming to the market. Phone and wireless companies love free OSes because they increase their profit margins. And, once enough people start to own Android phones, people will really start writing apps for Android phones. I don't think you'll ever see the groundswell the way you have with the iPhone SDK where people from all walks of life with no programming experience developed a desire to learn to write software, but I do think that there will eventually be a good market for Android apps and, therefore, for Android developers.

I'm happy to leave that market to others.

1 My apologies. My original wording here could have been read to imply that the Android team copied the iPhone SDK, which really wasn't my intent. I meant to say that some parts have a very similar feel and use design patterns commonly used in the iPhone SDK. It's quite obvious if you've spent any time with the Android SDK, that they are doing their own thing and are not just copying the iPhone
2 Every programmer goes through this phase if they stick with programming long enough. If you've been programming for a while and don't think you went through it, there's a very good chance you're still in it.