Being a small morsel of Android-specific geek entertainment involving an
example of the kind of thinking that being a Rubyist provokes which however
may be grievously wrong.
[This is part of the Android Diary.]
What happened was, I’m writing a little Android app to get my hand back in, which makes considerable use of Android Content Providers.
The Problem · Content providers (I’ll just say “Providers” from here on in) are a good idea, and allow you do to do some things in Android that would be awkward or impossible in other frameworks. A Provider is identified by what Android calls a Uri, and even though I’m pretty sure it isn’t really a URI, it’s a good thing to name data resources with short structured strings.
In practice, Providers front-end relational tables usually backed by
SQLite, which is
baked into every Android device. You provide the Uri, SQL
ORDER BY clauses, and the Provider gives you back a
which can be used to store and retrieve rows from the table.
The problem is, the API is sort of verbose and I always end up with lots of
boilerplate. The Cursor has
methods so you end up with a
do while loop, and then there are
methods for retrieving fields; you have to provide a data type and a column
number, and it also will provide a list of the column names in order.
Since I’m an Object-Oriented kind of guy, I’d like to have an object representing whatever-it-is that’s coming out of the content provider, and, given the name of the fields I care about and their types, that should be enough to do the job.
That’s what I called the code. Because it says Google on my business card,
can I now say
package com.google... without asking anyone? I may
have to apologize later which as they say is better than asking for permission
Anyhow, the code’s on Google Code; before I provide that link, check out
the JavaDocs, which I haven’t yet figured out how to stage there.
First look at the
and enjoy the simplicity of
for (call : calls), and then check
class that it relies on.
To summarize: make a class that extends
Builder, equip it with
setXxx() methods for every
xxx field in some
ContentProvider that you care about, and it’ll take care of looping the Cursor
and making the right getter calls against it and calling your setters.
It’s all done with sneaky metaprogramming tricks; for a statically-typed system, the Java language and Harmony libraries can be coerced into considerable dynamism if you hold ’em down and twist their arms. Those who care for such things may be amused by Builder.java and Reader.java.
Warning 1: For Java Programmers · This is what a couple of years of living in the world of Ruby can make you think are reasonable programming techniques. Of course, in Ruby, the required metaprogramming would have occupied a quarter the code and wouldn’t have required the developer to provide those setter methods. You’ve been warned.
Warning 2: For Androiders · Before sharing this with you, I sent a note to Reto Meier, my personal Android application-programming guru, entitled “Is this sick & twisted?”.
His reply included bad news (“Your solution... makes me nervous”) and good news (“it's such a convenient way to iterate over a cursor that the temptation will be to always use it”). I found his answer extremely educational; he’s written it up at Content Provider Iterator (or Things That Make Me Nervous). Check that out, and I’ll return to the conversation next week after I’ve had a chance to think some more.