Google Android SDK and Platform – review and analysis

Posted January 7th, 2008 by Nazmul

Comprehensive Real-World BlackBerry Training Courses by developerlife.com

Want to learn from the Masters? We’ve created groundbreaking BlackBerry software (we are finalists in the 2009 BlackBerry Developer Challenge). We have a complete set of instructor-led training courses available for BlackBerry development that will turbo-charge your BlackBerry development efforts. Whether you are a newbie or an experienced developer, we have modules that will fit your needs. Learn more about our courses & schedule.

Introduction

I’ve always been passionate about mobile user experiences, apps, services, infrastructure, and have spent many years working to create platforms using various technologies. I was really excited when the iPhone was announced with the availability of OSX… there was so much potential for that device to be a game changer for mobile. However, without the official inclusion of an SDK or a way to give 3rd party developers/ISVs a way to load software on to the device, it eliminated a lot of possibilities, on what 3rd parties could do with the device and platform, which is a shame. With the press releases that Google made about Android, it is marketed as an “open” platform, and without the restrictions that Apple places on the iPhone. It’s more “open” than Microsoft’s Windows Mobile and RIM’s Blackberry. So there is hope for this to be a good platform for developing mobile apps and services on. Or is it? In this white paper, I’m going to cut through the marketing rhetoric and do an in-depth analysis of the merits of the Android SDK and platform and discuss the problems that might arise due to it’s openness and the fact that at the time of this writing, there is not a single commercially available wireless smartphone or phone running Android. I’m not going to repeat information that you can get from Google’s Android website, which I reference where necessary for background information, and more indepth information.

Why I’m qualified to write this white paper

I’ve got over 7 years experience in the mobile/wireless sector, working on core technologies around delivering user experiences on mobile devices for the consumer and enterprise products/services. I’ve been involved in the creation of app servers and platforms dedicated to mobile app and service development, along with provisioning/deployment of apps to various devices (Palm, Blackberry, WinMo, J2ME, etc) over the years. Starting in the late 90’s when I created mobile app servers that could deliver instant messaging services to desktops, web apps, along with Palm VII devices (remember those?) that ran on a pager network. Then I started work on an complete app development platform for the enterprise market, with deployment targets being devices capable of running J2ME and PersonalJava, and devices running on the following OSes: Windows Mobile, Linux, Blackberry, etc. I’ve worked on high performance, low latency network software for these devices. I’ve worked on integrating ESBs, EAI products, along with J2EE apps and web services to mobile apps. I’ve worked on mobile geographic information systems before Blackberries ran Java, and had a Java based operating system. I’ve worked on first responder systems that ran on mobile infrastructure that leveraged just about any device they could. I’ve worked on prototyping wireless ordering systems for ecommerce for Starbucks, before they decided that they were going to work with T-Mobile and roll out WiFi to their stores nationwide as their primary wireless strategy (which has worked out beautifully for them). And my work hasn’t been constrained to the confines of an R&D lab… I’ve had the chance to try (and mostly fail and sometimes succeed) rolling out mobile deployments in the late 90s and early 2000’s when mobile infrastructure is not what it is today… the iPhone represented the holy grail of what I was doing. Back then, it was not possible to get a mobile operator to do anything differently… and today Apple can bend ATT to it’s will. My, how times have changed for the better. But as you will see from reading this white paper, the times might have changed, but there are still many old truths/constraints that still hold true and apply to Google Android.

No devices on the market, and the cons of too much hardware diversity

Despite Google’s marketing efforts to promote Android in the developer community, the elephant in the room is that there are no handsets on the market today, available to consumers that run the Android Linux based platform. Sure, it’s “open”, and sure it’s being marketed to developers, but this doesn’t have much bearing on consumer adoption. And the quality of the user experience, and how well apps work on this platform, will hinge on a large degree to the types of hardware that’s rolled out on various mobile infrastructures around the world.

What am I talking about? It’s great to have an SDK, but make no mistake, just because your apps run great, every time, on an SDK device emulator on your desktop/laptop, has very little bearing on what will happen to your app when you put it on a ‘real device’ running on a ‘real network’. I can recount countless times in the past, when I’ve built mobile software that ran great on the emulator, only to have issues on a real device… and it may have run great on most devices, but there may have been one or two important devices where things didn’t quite work right. The point is: there’s a pretty big chasm that has to be bridged for any of this Android hype to come close to becoming reality, and the apps that are built on the SDK to work as desired on a real device. Let me present you with some examples of how things might go wrong:

  1. Since Android is open, and Google wants there to be a proliferation of a lot of different types of hardware, all running Android, there might be issues that arise from this. Just because the same Linux OS and toolkits are running on different devices, doesn’t mean that there is tweaking that’s done which is unique to a device, which might make it better than another device. You will see this in lots of WinMo 5/6 devices. The same exact device works great from mobile operator A, but totally sucks on mobile operator B. Why? Each mobile operator tends to do lots of customizations and tweaking with hardware and drivers for the operating system before rolling it out to their customers. This is not a bad thing. However, this is what happens in the real world, and it’s something that people should be mindful of when they evaluate Android. A counter point to this is Apple’s iPhone – there is little to no variance in the type of hardware device that’s capable of running OSX… it’s completely under the control of Apple, and they can tweak, optimize, and test out their hardware/software stack before releasing it to the consumer market… making it immune to a lot of problems faced by platforms that run on diverse hardware architectures. Another example is RIM. They design their own hardware, run on their own network (which runs parallel to ATT, Verizon, etc), and they have a Java based OS and use JavaME for app development. RIM, despite have lots of models on the market today, and due to the tight control they have over tying together hardware, software, and service, to deliver a compelling user experience for their customers. Contrast this to Google’s approach, which is pretty hands-off at this point, in terms of tying this technology to a device or a set of devices.
  2. Android can run on very diverse hardware, with vastly different capabilities. While this might be perceived as a good thing, there are some major issues with making this real… making it so that software designed and implemented on the Android SDK and emulator works as expected on real devices. The problem with supporting too many hardware configurations runs deep into the core of Android itself. Let’s me give you an example of this. Android relies on multithreading and multiprocessing. It’s a modern OS and this is to be expected. However, if you set the bar too low and let “dumb” phones (as opposed to smart phones) run Android, then there are some serious consequences to this on apps that run on these low powered devices. One such ramification is threading. Each app in Android has to implement an “Activity”. An Activity must leverage background threads in order to process any kind of time consuming task… this is just like AWT/Swing, where you don’t want to hog the EDT (Event Dispatch Thread) otherwise you will freeze your app’s UI, anytime any long running tasks execute. On a low powered device, the hardware may not have the instruction set necessary to implement native threading, forcing the VM to implement “green threads”, which are really slow! So in a low powered environment, the less threaded your software, the better it might run! And this is contrary to the “way” or “tao” of the Android SDK and platform, which likes lots of processes and likes lots of threads!
  3. There are numerous input methods supported in Android, along with output (graphics rendering options). At some point, for an app to support the low end of the device spectrum, along with the high end, with the same code base, makes for some really complex and difficult-to-create apps! Despite the good intentions of the SDK folks and platform marketers and business people to embrace “open”, they are introducing tons of complexity in the implementation and viability of this platform, it’s apps, and devices to the end user! This is one of the problems with the SDK in it’s current state… You are supposed to be able to create apps that run on just about any kind of device… well, does it really make sense to even do that? At what point, does the complexity in your app’s business logic in changing it’s behavior based on the device hardware configuration get to the point where it’s easier to create multiple apps? One size fits all does not work! This is why in JavaME, there’s a CDC and a CLDC for different classes of device. Why in WinMo, there is stuff that runs on 2 types of hardware – smartphones and not so smart phones, etc. By making the SDK geared towards one size fits all, I think that creating Android software will be tedious, unnatural, and difficult… I will cover the APIs later in this paper.

Google’s inexperience in the mobile sector really shows. Even Microsoft has changed it’s strategy with WinMo7. Up until WinMo 6, they were relying heavily on their partners, and other players in the mobile/wireless ecosystem to create 3rd party apps, optimized drivers, etc. What they ended up with in reality is apps (mail, browser, calendar, etc) that were outdated for years, because partners didn’t put the work into providing their own implementations, and crappy driver implementations that made most devices very unstable! So with WinMo 7, Microsoft is going to take a greater share of the responsibility in the default apps and driver implementations to deliver a more consistent and stable user experience to the people using such devices.

The SDK and API

If you’ve read this far, you must think that all is doom and gloom with Android :) . This is partially true :) . More often than not, mobile offerings fail. Without owning all of the service delivery, and device integration issues, and by leveraging too much on 3rd parties to get it right, the end product is often compromised in delivering it’s intended/stated capabilities. The proof will be in the pudding, when there are real devices that can run apps without crashing; and when there are apps worth running, and devices worth buying. And when there will be more apps than just the ones supplied by Google. Marketing to developers as a way to create interest in the market is like putting the emphasis on the wrong syllable. Anyway, I will move on now to providing you with an analysis of the API itself.

SDK

For a pre release SDK, the m3-rc37a SDK is quite good. One thing I find refreshing and very useful about Android SDK is the awesome documentation. Google has really put a lot of work into the developer documentation around their platform, complete with tutorials, detailed API reference content, and lots of FAQs. The tooling around the SDK is pretty rough. Unless you use the Eclipse ADT, then you will have lots of issues getting the ant scripts to work, or to find integration with IDEs other than Eclipse. This is understandable given that these are early days for the SDK, but if you use the Eclipse plugin they provide, then things compile/deploy reasonably well. The emulator works ok. It’s really really slow, and it doesn’t work quite so well with the debugger, but again, I’m sure the quality of the tooling will improve over time, and I’m hoping there will be support for Netbeans and IDEA integration (the current plugin for IDEA doesn’t work, but these are early days so this is not surprising).

API

You can read all about the platform and architecture on Google’s website, they do a really good job of describing the platform and software ecosystem that exists in their platform. I am going to go over the APIs and application lifecycles (without repeating what is written quite eloquently on their website) in this white paper.

Managed App

The first thing that you have to keep in mind when building an Android app is that it’s a managed app, meaning that just like a servlet in a servlet container, where the container manages the lifecycle of the servlet (when it starts, stops, etc), a similar thing happens to your apps when they run in Android. The difference between the servlet container and the Android container is that the lifecycle is very complex in Android, and there are lots more parts and pieces that you have to coordinate with. This is a good document to read on the lifecycle of an Android app.

Before building your Android app, you have to be aware of the various lifecycle stages that your app will be put through by the container (Android OS), along with all the various subsystems that you will interact with in order to access data from existing apps, etc. Then you will also have to keep in mind the various types of inputs that you might have (touch screen, stylus, no touch screen, with keyboard, numeric keypad only, etc). All of these hardware form factor constraints will take a toll on the user experience if it’s not done correctly, and you would think that it can’t be that difficult to create a UI for mobile since there are so few pixels :) , but in reality, due to the constraints on types of input you can expect to have, you have to think about things you never have to on a desktop or web app. On a desktop app, you always assume there’s a keyboard and some kind of pointing device, and design your user experience and UI accordingly… not the case with mobile. I’ve seen many mobile apps that are utterly unusable, since the people who developed it didn’t take into account input constraints! Here’s a document on the Android website that talks about these issues.

Why does the Android container have such a complex set of lifecycle stages for your app? Since Android is a smart phone OS, your app may be interrupted at any time by: a phone call (incoming/outgoing), wireless connectivity interruptions, power off/standby, etc. So your app must always be ready to yield to other more important events/tasks that the user has to interact with more urgently than your app. And in order to be a good Android citizen, your app must respect all these lifecycle stages and implement them correctly, otherwise you might have issues. Here’s excerpt from this link talking about this:

“A common example of a process life-cycle bug is an IntentReceiver that starts a thread when it receives an Intent in its onReceiveIntent() method, and then returns from the function. Once it returns, the system considers that IntentReceiver to be no longer active, and thus its hosting process no longer needed (unless other application components are active in it). Thus, it may kill the process at any time to reclaim memory, terminating the spawned thread that is running in it. The solution to this problem is to start a Service from the IntentReceiver, so the system knows that there is still active work being done in the process.”

Ecosystem

Beyond the lifecycle that applies to your app, there are lots of different components in the Android operating environment that you have to be aware of and leverage. An Activity can be thought of as a starting point for user interaction with your app. There are other things like Service, IntentRecievers and ContentProviders that your app might have to implement in order to exist correctly/peacefully in the Android environment.

In order to avoid replication of code/functionality and to make it easy to enable interoperability inside the Android environment, there exist Intents. The idea is that apps/modules that are external to your code base aren’t referenced directly, rather an Intent is fired to the system, which then dispatches this event to the appropriate registered intent receiver, along with a URI that encapsulates the data for this “event”. You can register these IntentRecievers in the XML deployment descriptor of your app (which is where you identify all the Activity, Service, and IntentReciever components in your app).

Ok, if that didn’t make any sense, think of it this way: if you are familiar with Swing, think of an action event that get’s created by your code, and you provide the name of the action that you want fired (like edit or view or print), and you provide the data in the action event as a parameter, and then you ask the “system” to fire the action for you. The “system” then finds the appropriate module that can handle this type of action, and then fires it on that module, in the EDT. The module has to make sure that it’s “action handler” aka IntentReciever, doesn’t suck up too much CPU (can’t hog the CPU for more than 5 sec), because this will make the UI of your app unresponsive… just like you would freeze a SwingUI by uploading a 10MB file to the network in the EDT, or a Windows file open dialog box by getting a list of files to open from a really slow network.

The Swing analogy is pretty loose. In Android, you don’t actually pass a copy of data to the Intent, you merely provide a URI that the IntentReciever can use to retrieve the data it needs while it’s processing it. You will find this pattern everywhere in the API… in most cases you have to explicitly dereference a URI to get the actual data by invoking the resolver yourself – this can become very tedious in practice. If you are familiar with REST, then think of the structure of this URI as very RESTful. Since you can’t copy data into an Intent, in order to share data between various apps in the Android container, you must provide a way for another app to get to the data you meant to pass it. For this you have to implement a Content Provider. Most of the time you will have to use an existing content provider – eg, if you have to load a user’s photo from the system address book, then you will need to resolve the URI that points to the contact record into actual data via the Content Provider, and then query this result set to get the picture :) .

Simple, huh? ;) . Kind of like clear as mud, isn’t it? ;) . You might have to create a Content Provider yourself, if you want to play nice with other apps, and share data and interact with them via Intents. However, if you want a quick and dirty way for different parts of your app to get to it’s own data, then you can use this: Preferences file, data File, and SQLite database, in addition to the network (RPC, web services, etc).

An embedded database (SQLite) is also provided to you, along with desktop tools to access the data store, so that you can store relational data to the device’s permanent storage, and query it later. You can find out about all the components you have here.

Deployment and Resources

All Android apps have an application deployment descriptor. If you are familiar with web.xml on tomcat or your favorite servlet container, or more complex EJB deployment descriptors, then this will come as no surprise to you. The idea is to have your application declare all of it’s Activities, Services, and IntentRecievers with the Android container when your app is deployed to it. This is how the Android container knows who/what to dispatch Intents to (it uses an algorithm to figure out which IntentReciever to use in case there is more than one). So the AndroidManifest.xml takes care of registering your application and all it’s functional components/modules with the Android container. You don’t have to edit this descriptor file manually, as the Eclipse ADT plugin will gladly generate it for you.

You can also describe internal and external resources that your app needs. Resources can be anything from string bundles that you provide so that you don’t have to embed strings inside your application code, to image files, and any other files that you might need in your app. Android has a very powerful way to get to resources from your code, you can read all the details about it here. One really cool trick that Android has up it’s sleeve, to make it easy for you to use your IDE to get to resources that you’ve defined (via auto-completion features of your IDE) is to compile the names of your resources to a R.java class, so that you can reference it in your code seamlessly and easily. This is a great boost to developer productivity, since you don’t have to hunt and copy/paste the resource names into your code, but have it done using the IDE’s help, with the added benefit of getting notified when that resource is no longer available (via an compile time error). This part of the Android API is very polished and very flexible. A lot of the UI components know how to resolve references to resources automatically, you just have to pass them R.<your res here>, and they figure it out. Currently I8N support for the SDK is missing, but promised to be coming soon. As long as you use resources to store your string messages (instead of declaring them inline or explicitly in your code), you can start on the path to internationalization now.

One of the types of resources that you can create in Android is UI layout. You can describe your UI in XML and have the UI drawn for you without having to lay components out in code. This seems useful, but is actually really tedious to do without having a UI designer. But if you have a UI designer then you can have it generate code as well, so it’s a moot point for the most part if they provided a UI designer, which is not part of the SDK. That brings us to the next section on creating UIs.

UI

Like JavaME, Android does away with AWT and Swing or SWT in favor of it’s own UI component model and hierarchy. This is a pretty big barrier to entry, to have to learn this completely new API. Also, without a UI builder, it’s pretty tedious to have to learn this alien component model and then become productive in it quickly. This is one of the areas of the API that are very different than what most Java developers are used to, at least as far as building UIs go. Without an IDE to help build the UIs, this is also very tedious.

To create UIs in Android, don’t think in terms of regular GUI apps, where you have a main frame or window, inside which you layout various panels, and then swap between them as part of the task/work flow… Just like in JavaME, think in terms of Screens. Applications are disjointed, and instead of having one app, think of multiple activities and lots of screens. Think of Android apps in this manner. You have a bunch of screens that you have to design up front. Then you perform transitions between screens based on intents or actions. Then you have to perform some local or network tasks as a result of receiving an intent, which you should do in a service or in the background thread of an activity. If you embrace this mindset, then making apps becomes more palatable.

I hate to say this, but this “screen metaphor” is derived from the early days of WAP (which is crap, with which it rhymes too), and is something I personally despise! J2ME did the same thing when it came out, and it was overly influenced by WAP… but Android looks nothing like WAP, yet it has this disjointed app programming model, with this convoluted and unfamiliar graphics API, and screens… this is not going to help boost your productivity…

I’m a bit disappointed that an AWT-like framework is not provided, or even an “AWT translator”. I really like how GWT works, and how it hides all the underpinnings of it’s JS implementation and allows you to create apps in a way that most Java developers are familiar with. Given how much of the JDK 5 you can actually have in Android, I’m really surprised that they didn’t provide some AWT -> Android translator or something like that. And I say again, there is no UI builder, so be prepared to lay everything out in XML or in code.

Unlike JavaME, there’s a rich set of user interface components for you to choose from. You can find a well document list (with screenshots) of these here. There’s also a 3D OpenGL API that you will be able to harness in the future. This makes the choice of not using AWT or more desktop oriented GUI building techniques a bit baffling… it’s like they’ve dumbed down the API so that software will run on very low powered phones, by taking this WAP like approach, but they promise optional 3D graphics capabilities (which are limited to the underlying hardware supporting it of course). And here having too many choices, I think, gets in the way of productivity. Either standardize of fast hardware, or not… providing too much range in what is possible makes it very difficult to write software, and makes the developer/ISV make some implicit assumptions and choices… eg, if you leverage the 3D stuff, it won’t run on ‘dumb’ phones, only on smartphones… and then you ask, what kinds of phones will people buy? That’s how an ISV would know to develop apps for that target. And then we come back to the start of this whitepaper – there are no devices on the market!!! It’s very frustrating for an ISV to develop resources for a moving target that doesn’t exist :) . Many might not spend much time on Android, and just wait for the iPhone SDK, or develop for Blackberry, or WinMo, or all of the above, but not Android.

Java 5 API

I was very harsh on the UI stuff. Why? Because when you see the amount of Java 5 APIs at your disposal on Android, it will make you frustrated that they’ve provided such a large subset of Java 5 on a mobile device, yet have left out the UI stuff. You can port non UI parts of a desktop app to Android with relative ease. The VM supports Java 5 enums, generics, serialization! It even has lots of useful Apache Jakarta libraries (like HttpClient and others bundled with their VM). XML processing libraries are provided as well. This is where Android beats JavaME… in JavaME, you don’t have object serialization or the standard java.net networking stack… Reflection and other APIs that you are used to on a JavaSE 5 VM are available on Android.

Also, it’s very easy to import existing complied Java 5 code to use in your Android projects. Just add the necessary JAR files to your Eclipse project as a library, and the ADT plugin will take care of everything and put the libraries in your app.

Other goodies

A full WebKit browser is included in Android, and you can use this browser component in your Java apps! That’s a very cool feature that should exist in Java SE VMs! :) . Depending on whether hardware is available, there’s a Bluetooth, WiFi, Camera, GPS, compass, and accelerometer API. There is also a full suite of media support for common audio, video, and still image formats (MPEG4, H.264, MP3, AAC, AMR, JPG, PNG, GIF). I wish the standard JavaSE VM had these as well! :) . So Android actually has more capabilities than a full Sun JavaSE VM in that it has a WebKit browser that you can use in Java, and it has full media playback APIs :) . APIs are also provided for integration with Google’s services.

Best Practices

Given that it’s not easy to write mobile apps, especially for a platform that has so much diversity in the types of hardware that it runs on, Google does a good job of providing lots of best practices around how to build these apps: Writing efficient code, and Developing Responsive Applications.

The “Writing efficient code” document gets into how to make your Java code run faster on the Dalvik VM that comes with Android. This document is confusing for a simple reason… if you are running on a high end smartphone with lots of RAM (something like an iPhone or a new WinMo 6/7 device, or a new Blackberry) then you shouldn’t have to deal with the kinds of optimization they are asking you to make… then again, if you are running on a low end ‘dumb’ phone, then you would need to eek every bit of performance out by optimizing your code. This brings us back to the start of this paper. As an ISV or developer, how do you even begin to optimize your code, in alien ways, for a device that doesn’t exist, for a market that hasn’t yet adopted a clear winner, in terms of device or platform adoption! If you make a decision to support Android, what does that actually mean? Are you going to write apps for smart phones running Android? Or dumb phones? We have a chicken and egg problem again.

Closing thoughts

Sadly, there isn’t a lot of tooling or framework support around making it easier to create background tasks, since most developers aren’t at home with multithreading. And the strange UI API makes it even more alien to develop Android apps, when you combine it with the new lifecycle stages that you have to support in your app along with the other new APIs that are Android specific (content providers, intents, etc). This increases the barrier to entry for Java developers who can’t leverage their familiarity with AWT or Swing or other frameworks, when the transition over to Android, despite the fact that Android has such strong support for Java 5. It would be interesting if Google took a “GWT-like” approach with the Android SDK. That would reduce the barrier to entry, by allowing developers to easily and quickly write code in a simple API, that can then be translated to a more complex/lower level/native API.

Comments, feedback

If you want to share your thoughts/opinions on this paper with me, click here.

Training Services

Want to learn from the best in the business? We have training programs available for BlackBerry development, Android development, rich desktop apps, and UX design. We can give your development team a competitive edge, and make them experts in these technologies. Contact us if you are interesting in learning more about our training services & schedule.

Consulting Services

If you need help building web, mobile, and desktop apps that are all connected to the cloud, we can help. We can empower your business by bringing your ideas to life. Contact us if you have a project you need our help with and we will consider taking you on as a client.

Our expertise: architecture, UX design, graphic design, and implementation services for BlackBerry, Android, GWT, desktop Java, and cloud computing. Our specialties: crafting stunning UXes, LBS, real-time collaboration and syncing between services and web/mobile/desktop apps, location based mobile e-commerce, and location based mobile advertising.



Comments are closed.