Latest Tweets

 

Can the GVM library be used on Android?

…say to cluster points in a map based on the zoom?

(information about the GVM Java library)

I was just asked this question by email, and thought I’d respond via a blog post in case the same query recurs. This short answer is: I certainly hope so, it’s exactly the kind of task the library was designed for, but there are some caveats:

  1. I’ve not personally used the library on Android - there could be some minor incompatibilities due mismatches between the standard Java APIs and Android (though I don’t anticipate any). Should such an issue arise, I’m sure it could be patched very quickly.

  2. As standard, I would typically use the implementation in the com.tomgibara.cluster.gvm.dbl package that uses double coordinates. But since double arithmetic may perform really poorly on handsets (I don’t know) it may be necessary to use alternative coordinate types for better performance (the float based com.tomgibara.cluster.gvm.flt for example). Note that whatever primitive coordinate-type you use, it will not avoid all double arithmetic.

  3. How many points do you have device side? Making point clustering worthwhile when panning and zooming freely around a map implies to me that there are lots of points. A natural question is how do these points find their way into the application in the first place? Downloading 1M points in response to a query and then clustering them into 30 groups for display is probably not a good use of the device’s resources. Of course GVM could be used server side too, to provide a quick result to the user while lots more results streamed in for clustering in near-real-time.

Finally, I’d add the comment that GVM is very well suited to exactly this sort of application because of the flexibility that it provides around cluster keys: each time a cluster is enlarged or merged, the application is given the opportunity to modify the key - this means that the cluster key can be used to maintain all the salient state for the application (and no more, so performance can remain good).

In this online demonstration the cluster is keyed against the most populous city in the cluster but this could easily have been something else entirely.

Reservations about the Web Intents system

This is a repost of a comment I originally made on Paul Kinlan’s blog. Since it appears that moves to adopt Web Intents in Chrome and other browsers are progressing quickly, I felt that I should reiterate my reservations here.

I’m excited about the prospect of an intent mechanism for the Web to parallel that provided by the Android framework. The Intent has demonstrated itself to be an extremely useful abstraction that broadens the range of applications that it is possible to write; it facilitates the creation of smaller applications that, as a consequence, have greater scope for reuse.

Bringing these benefits to the Web is something I’ve given some thought to (on and off) over an extended period of time, so when I read this post I had already formed a conception of how intents might work on the Web, which it turns out has many similarities and some key differences.

Firstly, I think there is some basic semantic confusion in the API as I understand it. Intents in the Android system can be formulated by one application but handled by another on the basis of its registered IntentFilters. In the web intents API, this distinction appears to have been elided; the <intent> element does not encapsulate an intent, but an intent filter, so is misnamed in my opinion. The <intent> element is also less expressive than the equivalent IntentFilter construct in Android which:

  1. can match on URLs not just MIME types
  2. can restrict matches based on categories
  3. can match more than one action

Each of these have important use cases on the Web:

  1. allows one web application to hijack an “intended” link to another. Example: an intent to view a Flickr photo by linking to its URL could be delegated to an application that displays Flickr photos in a way that is more to the users liking.
  2. allows intents to be sensibly filtered for the user. Example: An intent might require that the UI for an activity be embedded within the current page (ie. in an iframe), an intent filter could use a category (corresponding roughly to the Android CATEGORY_GADGET) to indicate that it supports this.
  3. avoids verbosity in intent definitions. Example: No consensus exists for the denotation of some specific action, and there are a large number of equivalent alternatives; a single intent filter could match them all.

Personally, I think it’s questionable to embed tags directly into the HTML to record this information. The cost of repeatedly downloading and parsing these tags (which could be numerous) seems out of proportion with the frequency with which the information would be acted upon by a user. In my opinion, a <link> tag to an XML document containing intent information is more in keeping with established patterns (eg. linking to stylesheets or RSS feeds) and provides for greater efficiency since the linked document can be cached by the browser.

And I think that assigning the responsibility of intent selection to the user-agent is a poor choice too (assuming I’ve understood this correctly - the post refers to intents being recorded by “the system” so it’s not clear). My reasoning is partly based on the history of browser plugins, which has been one of progressive deprecation and irrelevance, and originates (I suspect) in the inertia of users: who wants the near-immediate satisfaction of a web page interrupted by the demand to install a plugin? Web Intents could suffer a similar rejection if users are frequently called on to find/choose matching web applications to perform simple actions.

But I think there is another factor that accelerated the descent of plugins: users have gradually become conditioned to expect uniform behaviour of web applications across any browsers. Installing a plugin into one browser would probably have been tolerated better had users not begun to access the Web from such a multitude of devices. It simply isn’t satisfactory for users to go around configuring each system they use to browse the Web.

When I sign-in to Gmail —from any browser— absolutely everything I have customized about the functioning of that application is remembered and it simply works in the manner I’m accustomed to. Were Gmail to adopt Web Intents it would be jarring (and simply inferior) if, when accessing it from someone else’s browser, I was subjected to their intent handling preferences; I would expect my own. It would be better if the intents I had registered, and my preferences for them had been stored in ‘the cloud’.

This leads on to an important question. Android Intents work as well as they do because a privileged system process acts as a broker between applications. The Intent data transferred between applications is stored and transmitted to solely to the system process, resulting in a robust and secure basis on which complex application interactions can be built. The question is, what should that broker be on the Web? I can only see two main candidates: the browser and the cloud. The conception of web intents appears to lean heavily on the former. I can see limitations in both, but my gut (and it’s nothing more than that) tells me that the cloud (if its feasible) is a better fit.

Rendering Android Views in the background

The Android AdapterView classes are very efficiently implemented and provide developers with a solid basis for creating fast, smooth views over arbitrarily large datasets. Their basic APIs have remained stable since Android was introduced and yet, based on the applications I try-out (and even some I use regularly) it seems that developers often make poor use of them.

This is the first of two posts that I’m hoping will improve this situation, by sharing some of the code I’ve developed for my own applications.

Creating smooth Adapters

The performance of an AdapterView is mostly determined by the Adapter you provide it with. There are two core obligations when developing an Adapter that will provide a smooth user experience†:

  1. Items must be returned without delay.
  2. Views must be returned without delay.

It’s that simple… Except what happens when your items are records that have to be retrieved from a Web server? And, to compound things, what if displaying the record requires downloading a couple of images? These problems can actually be tackled separately. This post provides a base class that helps with 2 (I’ll provide code to help with 1 at a later date).

Complications

What makes 2 complex in this scenario is that there’s no time to do anything other than return a preliminary rendering of the View from the Adapter, so the work to produce a complete rendering of a View must be done on a background thread.

Unfortunately, what makes this still more complex, is that the efficiency of classes like ListView and GridView is only possible because they recycle the Views they use to render items. This complicates the task of asynchronously updating the View because during the interval in which the complete content for the View is being generated, the parent AdapterView may have assigned it another item to display (possibly many times). In this case the existing rendering task should probably be abandoned (it certainly shouldn’t get assigned to the view) and instead a new rendering needs to commence.

Of course, this situation may itself be temporary: A user may briefly scroll an item off-screen and then back again; we don’t want to keep restarting the same rendering task without making any progress. To handle this efficiently caching may be necessary and may need to be combined with partial updates. And, as if things weren’t complex enough, the re-appearing item may be assigned to a different View to the one that initially displayed it (even if its position on-screen does not appear to have changed for the User).

A helpful class

So, yes, there is some complexity around implementing a good Adapter, but many Android developers have had years to get this right! Hopefully this code will help: it handles all of this apparent complexity in what is a fairly simple base class called ViewRenderer.

It’s designed to be invoked within the getView() method of Adapter. In this approach the getView() method should be limited to:

  • Obtaining rendering parameters for the specified position (most often this will simply be the adapter item)
  • Recycling the old View, or inflating/constructing a new one (but not customizing it for the item)
  • Calling the renderView() method of ViewRenderer to perform all subsequent customization of the View.

To make this work, you obviously need to customize the ViewRenderer with your own rendering logic. This is done by implementing the following three methods:

  • void prepare(View, Param, int) This method is called on the main application thread before the View is first displayed to the user. It’s your applications opportunity wipe-down the View (since it may have previously presented another adapter item) and display a quick placeholder/loading view.
  • Render render(Param, int) This method is called on a background thread and does the slow work (eg. drawing or loading) to convert the item into the resources needed to display it (eg. a Bitmap or POJO).
  • void update(View, Render, int) This method is called on the main application thread to apply a new render to a previously prepared View.

And that’s pretty much it, everything is reduced to these three digestible chunks. The int that’s being passed into these methods specifies an optional rendering pass to accommodate progressive rendering. There are a few additional operational aspects that can be controlled: render caching, view tagging, thread priority and execution. Documentation for these and everything else can be found in the source code comments.

ViewRenderer code

The code is amenable to a number of improvements (some possibilities are noted code comments), but I hope it’s useful and results in some smoother Android lists and grids, and here it is:


† Not creating garbage helps too.

Yoke Update

I’m currently in the closing months of an extremely involved enterprise e-commerce project that is occupying all of my time (pretty much), which is why I appear to have fallen off the Internet… but I am still here.

One concrete milestone I have reached in the last couple of months is to have version two of my Yoke server project published. Version one added support for users to share via Android applications. Version two has added preliminary support for developers to promote their Android applications.

Early support for App promotion

The first glimpse of this functionality peeking through into my own applications can be seen in this customizable app promotion widget that now accompanies all of my mobile apps:

It’s generated by application data stored by Yoke and inserted via a simple JS include onto any webpage. Without JavaScript, the widget safely fails-over to a link that takes the visitor to a simple webpage that contains the same information:

It’s a convenient way to ‘socialize’ my application download links and manage them from a single console, which currently looks a bit like this:

What’s next

I’m now slogging my way through an email pile-up and trying to carve out some time for my own development work prior to returning to it full time. So what do I have planned?

Mainly to start yoking all of my applications together. Progress on my mobile apps is well under way and I’m working on rolling Moseycode and Betan in too.

The risk of OAuth in mobile apps

I recently implemented OAuth for the Yoke service I’ve been developing. Yoke sign-in currently uses OAuth 1.0 for Twitter integration (via twitter4J) and a homespun OAuth 2.0 flow for Facebook and is used within my Android applications via a WebView. The regular Android approach would be to use the AccountManager API, but there are a number reasons I chose not to use it:

  • Backward compatibility. I have some old applications that I want to continue to support on devices which predate the API.
  • User permissions. Anecdotal evidence suggest that the permissions required to use the API scare some users away.
  • Absent providers. The API requires that the relevant account provider has been registered, this may not be the case, leading to an inconsistent user experience.
  • Convenience. Yoke has a growing web element; using HTML based authentication allows for significant code reuse in a critical part of the application.

At the time, these all seemed like pretty compelling reasons to choose OAuth for my applications, and they still do. But now I think that it could be a risk for users to register via OAuth within mobile apps, especially Android apps. Why? It’s simply this:

The security of OAuth is predicated on the use of an honest browser client, within mobile apps this cannot be assumed.

Nothing prevents a malicious application developer from bundling, into their app, a browser component that mimics the behaviour of the native one. On Android, this is made easier because the source is open, and there isn’t any pre-vetting of apps published to the Market.

A compromised browser could readily skim off your password and log it to a server and it would be difficult, if not impossible, for you to discover that your credentials had been stolen in this way. The problem is that we are all conditioned to look past the browser, and to recognize the sign-in pages of the online services we use (Google, Facebook, Twitter etc.) and to give them our trust, unconsciously.

I will continue to provide authentication within Yoke apps using OAuth since I’ve invested time implementing it, but in the future I may be a little more cautious.

Improving Google Analytics performance on Android

A few months ago I discovered that the Google Analytics Java library for Android can interfere with the performance of your application because it accesses a database on the main thread.

Not wanting to abandon analytics, I’ve been using this class ever since. It’s a useful wrapper around the GoogleAnalyticsTracker class which I thought I’d share because it’s simply very useful. It:

  • Enqueues tracking events on a background thread so that the main UI thread is not blocked.
  • Provides high-level event-categorization and filtering based on categories.
  • Records statistics on the underlying Google analytics tracker.

Using it is very simple, here’s an example:

And here’s the class which you’re welcome to use in any of your own projects.

A screenshot showing the detail from the meadow live wallpaper. Naturally, the thing looks much better in motion, but the screenshot does a good job of showing the individual blades of grass.

A screenshot showing the detail from the meadow live wallpaper. Naturally, the thing looks much better in motion, but the screenshot does a good job of showing the individual blades of grass.

A meadow inspired Android live wallpaper. My usual dreadful videography aside, I’m pleased with this effort.

I thought I’d try coding something for my new Samsung Tab 10.1 that Google provided to attendees of Google I/O 2011.

It’s an old piece of code that I thought I’d dust off try out on the tablet. Around 2,000 individual blades of grass contribute to the sensation of a meadow on a blustery day.

Smartphone support for CSS: handheld

A rant (contains some immoderate language)

Software companies large enough to have responsibilities of stewardship over common aspects of the Web often make inferior technical decisions for no reason than their short-term gain at the expense of long-term benefit to everyone. Usually I let this wash past, I’m acutely aware it’s happening, but I don’t let it derail my thinking or my work. But sometimes — I just can’t help it — something will just piss me right off. Invariably it’s something modest, something that would simplify my life as a software developer, or open a small pocket of creative possibilities; invariably something that’s put to death as part of the collateral damage of a corporate business plan somewhere.

This time it’s the handheld media type for CSS. This harmlessly enumerated value promised to give developers a way to tailor websites for display on handheld devices. It was introduced in the CSS2 specification 13 years ago, with the following straightforward description:

Intended for handheld devices (typically small screen, monochrome, limited bandwidth).

Technology moves quickly and this was subsequently amended to:

Intended for handheld devices (typically small screen, limited bandwidth).

Any rationally minded individual would, I think, agree that any iPhone is by definition a handheld device. One that, whether it’s typical or not, has a small screen and limited bandwidth compared say a desktop or laptop computer, two other device classes that are frequently used to browse the Web.

So why does the Apple iPhone not classify itself as a handheld device? Here’s Apple’s justification:

CSS3 recognizes several media types, including print, handheld, and screen. iOS ignores print and handheld media queries because these types do not supply high-end web content. Therefore, use the screen media type query for iOS.

This is dross: superficially intelligible, but still drivel. It’s the sort of thing we pay our politicians to say because no other people of equal intelligence can bear to, except this is embedded in a technical document describing how to develop webpages for the iPhone.

CSS rules control the presentation of content, they have nothing to do with its “supply”. The most you could say is that CSS rules might be used hide “high-end web content” though I really struggle to see how this could ever be a real problem because a developer would never want to serve “high-end web content” to a device that doesn’t have the bandwidth to usefully download it or the screen to usefully display it only to finally hide it from the user when it had; and a strategy based on the assumption that content which is never visible is never downloaded is very risky.

This appears to be a manufactured justification. Apple is full of smart people, the only rationalization I can find which makes sense is that Apple didn’t want customers opening their stylish cardboard boxes and turning-on their expensive new gadgetry and launching their petite new browser to see monochrome pages filled with undersized text, if even from a handful of websites. Fair enough. It may have increased their bottom-line, but it’s paid for by every web developer who wants to reliably style their web pages for mobile phones, and it’s really biting us in the backside now that the screen resolutions of high-end phones overlap with those of low-end computers. It was a problem for Apple, but they side-stepped it, and exported it as a problem for (potentially) every web developer in the world.

That Android followed the iPhone down this dead-end just increases my frustration because it means that support for the handheld media type will never improve. Grrr…

I’ve made some minor edits for accuracy

Yoke Sign In

I finally found a little time to do some Android coding. The result is a new sign-in flow for Yoke:

Here I’m trying to make it as simple as possible for users to establish an identity with an application. The activity is part of a generic Android library I’ve developed that matches an app’s look using style declarations to override the default appearance.

There’s also a nice technique in use here: The explanatory text is in a ScrollView. To bottom align it when the text doesn’t fill the view I combine the attribute android:fillViewport with a vertical LinearLayout (to hold the text) that contains a trivial zero-height View of weight 1. The result is that, when the text is smaller than the ScrollView, the trivial View soaks-up all of the empty space, pushing the text downwards, and when the text is larger than the ScrollView, the trivial View get squeezed to nothing.

The Google favicon is a placeholder — does anyone know of an approved icon I can use?