I’ve been working on a project called Yoke. It’s a server application for enhancing mobile applications and it’s accompanied by an Android library that takes most of the effort out of using Yoke in Android applications.
I started working on Yoke because there were a number of features that I really wanted to add to my Android applications for which I lacked a good approach. My key problem was:
How to make user generated content shareable?
Mobile devices typically have spotty internet connections, so if you want to make the user generated content accessible in a reliable way it needs to be copied to a server. And unless you want to prevent users from editing their content after they have shared it, you need a way to update content that’s already been uploaded. And since it would be quite annoying for a user to request these updates manually, it needs to be done automatically on their behalf (without failing “annoyingly” if the network fails). And since users might use the application on more than one device it’s necessary to synchronize the user content between all devices and the server, in both directions. Using the application across multiple devices in this way further implies that each user needs some form of identity within the application.
Then there’s the actual user mechanics of sharing to consider. Although sharing within an application can be as simple as making content visible to all the other users, the reality is that, for even mildly popular applications, the volume of content generated requires indexing and sorting to make it navigable. And because user generated content naturally varies in quality you need a mechanism for surfacing the best content. Approaching this (as I have) by allowing users to ‘like’ or ‘favorite’ the content of other users involves many other considerations: how to cope with flurries of ‘likes’ on extremely popular content, how to provide a stable ordering for browsing by popularity when it is constantly fluctuating, how to accommodate content that isn’t public, etc.
Simple sounding problems can hide a lot of complexity. Yoke is my attempt to write a reusable platform that does only as much as I need to let users share content via my mobile applications. I just want to give them an easy way to:
in a way that doesn’t constrain the applications I can write.
I think I’m almost there now, Metaglow has been my testbed which I’m looking forward to releasing soon, after that I’m going to try and find time to write a few posts about what I learned by implementing Yoke.
I take accessibility very seriously, so I’m really glad that new guidance on accessibility on Android has been made available to developers.
One of the problems with designing accessible applications is that it’s very easy to overlook the needs of users when you don’t share those needs. This is compounded when users have diverse needs which is the case when considering accessibility; the blind or partially sighted have completely different needs from the deaf or those who are hard of hearing.
It also doesn’t help when you make mistakes like this (from my Metaglow app). This all looks okay on the surface (but not especially great): simple layout, Dpad navigable, labelled buttons.

Until I considered the implications of my general design for this activity:

Which I belatedly realized leaves no way of navigating to the tabs at the bottom of the screen, except by touch: with focus falling naturally on the first element in the grid, the user can never move down far enough to reach the tabs because the list of favorites is effectively infinite for UI purposes.
Fixing that mistake involves too much re-work for the first release, so I’ll have to stick with the misdesign for now. Here’s a tip: don’t combine heavily populated AdapterViews with bottom-tabbed activities.
I’ve been unable to code for the past week, so as I started to ease myself back in today, I took time to investigate a phenomenon I first noticed months back.
Reto Meier has been a strong advocate for the use of analytics, his code and all the available sample code indicate that you call the analytics tracker on the UI thread. But if you use the Google Analytics SDK for Android like this, calling the tracker on the UI thread, it can make your app very unresponsive. I noticed this after adding the library to my Metaglow application, buttons that had felt very snappy immediately felt sluggish, even though I’d taken care to keep the UI thread ‘hygenic’.
Today I sat down and wrote a little stub of code that collects some basic call-time statistics for the GoogleAnalyticsTracker class from version 1.1 of the SDK. I made a few runs on my Nexus One by proceeding to use Metaglow over an extended session. In each run I collected timings for approximately 100 calls to the trackPageView and trackEvent methods.
Of the three runs, these were the most typical numbers (one set slightly was slightly faster, one set was significantly slower):
So, you can expect users to occasionally encounter UI glitches of 1/5th* of a second or more just from queuing an analytics event; and (admittedly I don’t have figures for this) it’s my experience that the pauses are more significant than this; infrequent, but long when they occur; this gives a bad user experience.
It’s documented that the analytics data is queued into batches and dispatched separately from the call that records them, so this behaviour (infrequent but lengthy pauses) can’t be due to network I/O. But it is what we are told to expect when we are performing writes to Flash storage. So I used traceview to peek inside the execution of the analytics code and confirm that this was the cause.

Those green blocks, which are just about visible, are writes inside Sqlite3 and this explains the uneven performance.
Since I want to keep analytics I will probably write my own event queue around the Google analytics tracker, to decouple it from the UI thread. If you use Google analytics and want to give users a smooth experience, you may need to do this work too.
(*) this figure is based on 2 standard deviations above the mean
Yesterday I read a blog post which was wholly negative about the !# syntax that’s becoming increasingly popular in the URLs of modern AJAX websites. There are good reasons to be concerned by the broad adoption of hashbangs, since it is a shift away from the well established principle that a URL directly informs the server which resource is being requested (without depending on any interceding Javascript) because it makes serving, bookmarking and indexing more robust.
However, the post was inaccurate about the drawbacks of hashbangs, and I think its author failed to recognize its necessity in some cases. So what, someone is wrong on the internet, which wouldn’t normally bother me, but when I saw the arguments being propagated, I felt it was necessary to post corrections.
First in rebuttal to first the post I read:
Caching, by proxy server or otherwise, is not broken by using AJAX or even a hashbang. The JS/XML fragments served for page content are as elligible for caching as any other content. On the contrary, AJAX often improves cachability, because instead of serving one entire webpage whose content is rendered uncacheable because of small pockets of dynamic content, JS can compose the HTML from separate JS/XML fragments each with their own expiry headers.
It is quite true that only RFC-2396 compliant crawlers will recognize the content. But if you need what hashbangs provide (see below) you are no worse off than if you just used a hash. And if you anticipate that the RFC-2396 standard will see broad adoption (which I do - how many search engines can ignore Facebook and Twitter?) then the concern is diminished.
I don’t see any negative implications for Microformats other than those that were already present in the adoption of AJAX.
The Facebook “Like” widget and other such services already have access (via JS) to the full URL of the page and this includes the fragment. Such services simply need to preserve the fragment in the case that it starts with a !.
Finally, the author dismisses adoption of hashbangs with:
Engineers will mutter something about preserving state within an Ajax application. And frankly, that’s a ridiculous reason for breaking URLs like that.
which is a blasé dismissal of one of the engineer’s core responsibilities, which is to preserve application state in a way that is consistent with the user’s expectations. It boils down to this:
then you must use hashbangs. Occasionally, for reasons of usability/performance, the first condition isn’t an option - and who wouldn’t want the other two?
I’m certainly not advocating that hashbangs are a good thing, or even desirable: I’m a huge fan of progressive refinement (and her sister graceful degradation). But engineers make judgments based on the priorities associated with their website/web-app; though these decisions should be informed by the web’s history, they shouldn’t be bound by them or we’d never have anything new on the web.
One parting comment, which I’ve been intending to make for a very long time…
I’ve been doing lots of Android development, which features a lovely system of Intents which act as entry points into the components of Android applications. These objects capture the information that an application needs to restore a user’s activity within the application; precisely the sort of information that web app developers are attempting to shoehorn into the URL.
So it’s a terrible missed opportunity that Android doesn’t provide either a way of externalizing Intents (as URLs provide for on the web) or alternatively, allow applications to expose their present state as a URL. It would open-up new possibilities, most obviously the ability to bookmark and potentially share one’s location within an application. Think how much more simply Google Analytics would have mapped onto Android had this been considered.
It’s ironic that web developers are trying to fabricate Intents from URLs, while Android developers are stuck doing the opposite.
In a previous post, I described how I could dynamically generate a continually evolving logo by masking and layering several different bitmaps.
This worked well enough, but failed to look convincing when the rendered texture was light. I overcame this by creating a halo effect, to make brightly textured emblems appear to luminesce. Again, the 2D rendering apis in Android made this very easy.
I start the process with the rendered texture in a Bitmap:

Using a Canvas over a tiny 3x3 Bitmap I produced a scaled copy of the texture.

Using the Bitmap.getPixels() method, I created a SweepGradient through the eight outermost colours.

Finally using a black-to-white-to-black RadialGradient applied with a PorterDuff.Mode of MULTIPLY a circular ring is of compatible colours is created:

This ring can then be overlayed separately onto the existing image, using the useful TransitionDrawable class to smoothly switch halos.
The final effect can be seen in this video
This a copy of a response I left on Al Sutton’s blog. It tries to explain with a simple example, why I would be uneasy allowing Amazon to adjust the pricing of my Android applications. I have no plans to sell any of my applications through Amazon. There are several reasons for this, but here’s one:
Suppose I run a company which has spent $100,000 developing an Android application that has a ‘list price’ of $1. Like all hopeful businessmen, I am expecting the application will be popular – but I don’t know.
I put the application for sale on the Google Market and the Amazon Market. In what follows I’m going to ignore tax to simplify things, and keep the analysis tractable by assuming that all customers have access to both markets.
Let’s look at three scenarios:
Contrary to my hopes, the app is not popular. It sells 500 copies on each market, earning the company a total of $700. Amazon don’t bother to promote or discount this unpopular application.
The app is well received, it sells 50,000 copies on each market, earning the company a total of $70,000. Amazon decide to adjust my price in an attempt to boost sales. It works, the price is halved and it sells an extra 100,000 copies at 50¢ netting an extra $35,000. Relief, the company has broken even (anyone who has actually run a company on a P&L basis will empathize at this point) but with a profit of only $5000. Note however that Amazon have made any further sales in the Google Market very unlikely.
The app is wildly popular and 1M people want to buy it! If the pricing remained unchanged, this would bring the company $700,000 revenue. But Amazon are tracking the download numbers and the interest in the application becomes obvious immediately. Amazon reason that by reducing the sale price of this popular application they can double their sales of the application by taking all of the sales that would have gone to the Google Market. They will also benefit from the additional traffic to Amazon Market in the form of extra sales of other applications. So they halve the price; it makes little difference to the number of sales because people want the application anyway. Every purchaser buys the application from the Amazon Market instead of the Google Market because it’s cheaper there and the company makes $350,000. Amazon have just cost my company $350,000!
Given that, as the person running the company, I’m only likely to invest time in developing applications that I hope will result in (3), why would I sell my application via the Amazon Market?
I’m pretty sure that I’ve seen a few questions asked about stuttering framerates within Android games that were be traced to the garbage collection of String objects generated by Integer.toString().
Avoiding GC cycles is important in animations and games. The Android Canvas class helpfully gives you a drawText method that takes a char[] rather than a String for just this reason.
All you need is some code that will write your integer into a character array. Here’s a small class just for that:
Playing with the latest Android Google Maps application, it reminded me that it contains one of my favourite icons. I’m aware that few people will have even considered the possibility of having favourite icons, but that doesn’t stop me having them.

This icon appears within Android Google Maps to provide users with a route back to the map view from other activities in the application. Here are reasons I like it:
I think it’s a small masterpiece of icon design.
The mystery is solved. You need to disable both the satellite and the terrain layers to make the 3D buildings visible.
I’m not sure if this was me being slow witted or if there’s a usability issue. Then again, “I want to see some 3D buildings” it’s not really a core use-case is it.
I’d really like to see some 3D magic on Android Google Maps 5.0, but where are the buildings?
These are screenshots where I’m zoomed in to the maximum possible extent in terrain mode and zoomed in close in satellite mode.
And I haven’t just looked in Cardiff either.