Brain Flush

January 10, 2010

Introducing Calculon – a Java DSL for Android Activity testing

Filed under: Mobile Devices, Software Development & Programming — Tags: , , — Matthias @ 1:05 pm

I have been working on a new test library for Google Android lately, a project which I’m very excited about, and which I feel has loads of potential: Calculon, an Android testing library which lets you write functional tests for your Activities using a very concise and natural syntax.

I am a big fan of test-driven development, and I think there’s no arguing about the massive benefits you get from backing your software up with an automated test suite. The support for writing tests in Android, however, is lacking at best. Even though there has been a test runner since the 1.0 days, writing unit or functional tests in Android is far from being a pleasant experience. For me, the two most important things about tests are that they must be easy to write, and more importantly, easy to read.

That being said, here is a classic example of why Android testing sucks. Our test story is:

Assert that a click on ‘button’ launches a new BarActivity.

Without Calculon, what you do is this:

public void whatInHeavensNameDoesThisEvenTest() {
    final Button b = (Button) getActivity().findViewById(R.id.button);
    ActivityMonitor monitor = getInstrumentation().addMonitor(
        BarActivity.class.getCanonicalName(), null, false);
    getInstrumentation().runOnMainSync(new Runnable() {
        public void run() {
            b.performClick();
        }
    });
    getInstrumentation().waitForIdleSync();
    assertTrue(getInstrumentation().checkMonitorHit(monitor, 1));
}

So, I first have to retrieve a reference to the button that’s supposed to launch a new BarActivity. Then I have to create what Android calls an ActivityMonitor, that’s simply an object which just sits there and waits until an Activity is being launched that matches the description it was configured with. Then I have to perform the actual button click, but sorry, not allowed on the instrumentation thread, so I have to runOnMainSync(). We’re not yet there though: we have to sit and wait, because launching a new activity could take a while, so we also have to waitForIdleSync(). The assertion that follows also couldn’t be less expressive.

When I first wrote this test, my single thought was: Where the heck is my story? It’s buried under a heap of ugly boilerplate code.

I don’t care that the test runner cannot perform a view event on the instrumentation thread. I don’t care that it needs to sit and wait for the Activity to launch. I don’t care about ActivityMonitor and its crummy API. I just want to look at the test, and understand what it’s doing.

Let’s reiterate our test story:

Assert that a click on ‘button’ launches a new BarActivity.

With Calculon, this test is written as:

assertThat(R.id.button).click().starts(BarActivity.class);

Oh the beauty. Our test story was a single sentence, so is the test. That’s how it should be, really. There’s nothing worse than seeing someone else’s tests failing on the build server and having to dissect them line by line to figure out what it’s actually testing.

So let’s move on and look at some nifty Calculon tests. And remember: “Calculon never does two takes!”

Testing with Calculon

Calculon is in a very early stage of development, and currently it only supports writing functional Activity tests, using Android’s ActivityInstrumentationTestCase2. Here is what a Calculon test looks like:

public class FooTest extends FunctionalTest<FooActivity> {
    public FooTest() {
        super("com.example", FooActivity.class);
    }

    public void testStuff() {
        ...
    }
}

Nothing special here, really. You just inherit from a Calculon FunctionalTest.

Assertions

At the heart of a Calculon test are assertions. To create a new assertion, you use the assertThat() method:

public void testStuff() {
    // testing against activities
    assertThat()...
    assertThat(getActivity())...
    assertThat(someOtherActivity)...

    // testing against views
    assertThat(R.id.some_button)...
    assertThat(someButton)...

    // of course all Junit assertions work as well
    assertEquals(...)
    assertNotNull(...)
    ...
}

For now, there are two basic kinds of assertions: ActivityAssertion and ViewAssertion. There is also a third kind, ActionAssertion, but it takes a somewhat special role and is discussed at the end.

Activity Assertions

An ActivityAssertion is an assertion on the state of an Activity and is used like this:

public void testStuff() {
    // testing for an orientation
    assertThat().inPortraitMode();

    // testing for views
    assertThat().viewExists(R.id.some_button);

    // testing for input actions
    assertThat().keyDown(KeyEvent.KEYCODE_BACK)...

    // testing for custom predicates
    assertThat().satisfies(new Predicate<Activity>() {
        public boolean check(Activity target) {
            return target.isTaskRoot();
        }
    });
}

View Assertions

A ViewAssertion is basically the same, just that it tests the state and behavior of a view:

public void testStuff() {
    // testing for view state
    assertThat(R.id.button).isVisible();
    assertThat(R.id.button).isGone();

    // testing for input actions
    assertThat(R.id.button).keyDown(KeyEvent.KEYCODE_BACK)...
    assertThat(R.id.button).click()...
    assertThat(R.id.button).longClick()...

    // testing for custom predicates
    assertThat(R.id.button).satisfies(new Predicate<View>() {
        public boolean check(View target) {
            return target.getVisibility() == View.VISIBLE;
        }
    });
}

Action Assertions

This is a special kind of assertion. You always use it when you want to assert that some action (e.g. a click or a key press) does something. You can use it on both activity and view assertions, and it also allows you to delegate an assertion to another object:

public void testStuff() {
    // testing for actions that launch a new activity
    assertThat(R.id.b1).click().starts(BarActivity.class);

    // testing for actions that finish an activity
    assertThat(R.id.b2).keyDown(KeyEvent.KEYCODE_Q).finishesActivity();

    // testing for actions that change something
    assertThat(R.id.b3).click().implies(R.id.b2).isGone();
    assertThat(R.id.b4).click().implies(getActivity()).inLandscapeMode();
    assertThat(R.id.b5).click().implies(new Predicate<Model>() {
        public boolean check(Model target) {
            return target.someAttribute() == 5;
        }
    });
}

There’s more to come!

This is only a very early version. I intend to expand this library significantly over time. Of course it’s open source, so contributions are always welcome. You can fork the project on GitHub, add your changes, and send me a pull request.

May 19, 2009

The Force Unleashed: XML+XPath on Android using dom4j and Jaxen

Filed under: Linux & Open Source, Mobile Devices, Software Development & Programming — Tags: , , , — Matthias @ 1:15 pm

*UPDATE* This post has become obsolete. Google has bundled the Java XPath APIs with the release of FroYo (Android 2.2 / level 8).

*UPDATE* The source code is now on GitHub. Feel free to fork ‘n fix. Here’s the JAR: http://github.com/kaeppler/dom4j-1.6.1-harmony/downloads

I have been very disappointed with Android’s XML parsing support from day one, it’s simply too low level, inconvenient to use, and is lacking important features (I was especially disappointed with the decision to exclude the JAXP XPath support from Android, which has become an integral part of the JSE).

This is not only about cosmetics. Parsing XML documents of only medium complexity already turned out to be error prone and very tedious on Android (white space normalization problems, broken Unicode entity ref expansion, etc.) and we would’ve had to rewrite stuff which existing Java XML libraries already do in a graceful and stable manner.

Since I have always been a big fan of dom4j, I fixed an issue with the latest source tree that prevented dom4j’s QNAME caching to work with Android’s Java implementation (or more precisely, with Apache Harmony’s SAX implementation — the Android Java implementation is based on a pre-release version of Apache Harmony).

I haven’t committed that change back to dom4j yet, because development seems to have stalled on that project, but if anyone is interested, I can host the source code and a working JAR somewhere (please drop a short line in the comments section, otherwise I won’t bother sharing it).

dom4j also works very well in conjunction with Jaxen (a free XPath implementation)!

Some example code to wet your mouth:

SAXReader reader = new SAXReader(); // dom4j SAXReader
Document document = reader.read(xmlInputStream); // dom4j Document

// select all link nodes with href "http://example.com"
List linkNodes = document.selectNodes("//link[@href='http://example.com']");

// select an attribute value
String val = linkNodes.get(0).attributeValue("href");

// select element text and trim it
String value = document.elementTextTrim("childNode");

etc. pp.

Simple, powerful, straight forward — and performance is also decent (it’s pretty slow in debug mode, but reasonably fast otherwise).

April 8, 2009

Android In-Sync: Handling concurrent tasks in Google Android

UPDATE 15/12/2009: While the problem described here still applies to the latest version of Android, I discourage anyone from using the code linked here. I’ve bundled a better solution with my Droid-Fu library, which is a little more intrusive, but leads to much leaner code for the application developer.

Today I want to talk a little bit about concurrency in Android applications, and the problems it poses on the developer. If you have used Android on your phone before, it’s likely that you have stumbled upon applications which load data off the internet, or perform other time consuming operations. The problem with time consuming operations is that, well, they consume time, and if they aren’t perfomed concurrently to Android’s user interface thread (the main thread), then the UI will lock up — certainly not a good user experience. So, it’s pretty obvious that on internet phones like those based on Android, highly concurrent applications are more the rule than the exception.

I guess I don’t have to mention that developing concurrent applications is everything but simple. Keeping threads that share data in sync is not a trivial task and prone to errors. What makes it even more difficult in Android is the fact that while your application is loading data, it may suddenly be interrupted by an incoming phone call or because the user decided to flip the screen into a different orientation. You may think that your thread will get paused while the activity that created it is brought to the background (or even gets destroyed). That’s not what happens though: any thread will continue running until it completes, even if your activity or service is not alive anymore. And that’s where the pain starts.

Problem Statement

Consider the following news reader application (just as an example). To keep things simple, the application only supports one operation: Showing the latest news articles on the screen using pagination. When started the first time, the application loads the first 10 articles off the internet in a separate thread and renders a nifty spinner visual to keep the user happy. When the user wants to read the next 10 articles, a button is pressed, the spinner appears again, and the next 10 articles are loaded, etc. pp. We have two separate threads running concurrently in this application: The main UI thread that renders all the article items and the spinner graphic, and the thread that downloads data off the web and posts that data back to the UI thread upon completion, so the UI can update itself accordingly.

Now, what happens if a phone call comes in while we see the spinner graphic? What happens is that Android will pause your application (probably even destroy it) in order to launch the call activity on top of it, but your download thread will continue running in the background. It’s difficult to tell what is going to happen when that thread tries to post its result to an activity that doesn’t even exist anymore, but most probably that application will crash (for example when the download result handler in that activity tries to display a toast or dialog, which will be attached to a window that has already been destroyed). If that thread doesn’t terminate and still holds a reference to the calling activity, it may even produce a memory leak. Long story short, you will definitely want to introduce some mechanism that keeps the communication between activities, services, and any threads they run, in sync.

Solution

Lucky for you, it just so happens that I have written a module that does exactly that. Based on my former work on this problem and an excellent article by Eric Burke (who already presented an almost-working solution), I have come up with a Task class that you can use to dispatch long running operations from your activities and services and which also handles all the inconveniences arising from situations like resuming from an interruption (phone calls and the likes).

And here is how you use it:

public class Concurrency extends Activity implements TaskListener<String> {

    private static final int TASK1 = 0;

    private static final int TASK2 = 1;

    private Task<String> task1, task2;

    private Callable<String> callable1 = new Callable<String>() {

        public String call() throws Exception {
            try {
                System.out.println("task1 starting");
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                System.out.println("task1 finished");
            }
            return "task1 result";
        };
    };

    private Callable<String> callable2 = new Callable<String>() {

        public String call() throws Exception {
            try {
                System.out.println("task2 starting");
                Thread.sleep(6000);
            } catch (InterruptedException e) {
                System.out.println("task2 finished");
            }
            return "task2 result";
        };
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onPause() {
        super.onPause();

        task1.unregisterCallback();
        task2.unregisterCallback();
    }

    @Override
    protected void onResume() {
        super.onResume();

        task1 = Task.getOrCreate(this, TASK1);
        task2 = Task.getOrCreate(this, TASK2);

        switch (task1.state()) {
        case NOT_STARTED:
            task1.run(this, callable1);
            break;
        case RUNNING:
            System.out.println("task1 still running");
            break;
        case COMPLETED:
            System.out.println("task1 completed in background, result: "
                    + task1.getResult());
            break;
        }

        switch (task2.state()) {
        case NOT_STARTED:
            task2.run(this, callable2);
            break;
        case RUNNING:
            System.out.println("task2 still running");
            break;
        case COMPLETED:
            System.out.println("task2 completed in background, result: "
                    + task2.getResult());
            break;
        }

    }

    @Override
    public void onTaskFinished(Task<String> task) {

        if (task.failed()) {
            System.err.println("task" + task.getTaskId() + " failed. Reason: "
                    + task.getError().getMessage());
        } else {
            System.out.println("task" + task.getTaskId() + " finish handler: "
                    + task.getResult());
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_BACK) {
            Task.cancelAll(this);
        }

        return super.onKeyDown(keyCode, event);
    }
}

Let’s walk through that code bit by bit. First, our activity defines two task objects, task1 and task2, with IDs TASK1 and TASK2. What those tasks are supposed to do is defined using two Callable objects, callable1 and callable2. Everything that happens inside the call() methods of those objects will be executed in a separate thread. We also have to tell those tasks what will happen should they complete. We do this by implementing the TaskListener interface, which currently only defines a single method: onTaskFinished(Task). We can check in that handler whether the task succeeded or not by calling its failed() method. If any exception was thrown during the execution of call(), this method will return true and the exception can be retrieved by calling its getError() method. Otherwise, the return value of getResult() is guranteed to be whatever you return in the callable. The Task class is generic: You instantiate it using the return type of the callable you pass to it. This ensures type safety when working with the result object. The same holds for TaskListener.

A closer look to onResume() reveals that everytime our activity is resumed, those task objects are either already in memory or will be created for us by calling Task.getOrCreate(). If we already started that task during a previous life-cycle of our activity, we can poll its status to check whether it has already completed or if it’s still running. The former is the case if the thread had terminated while our activity was paused or even completely destroyed; in that case, we can simply pick up whatever result the task came up with in the meantime. We also call Task.unregisterCallback() in onPause() in order to avoid being called back by the task when the activity goes poof (not doing so may result in memory leaks, as described above).

Right now, the activity will pick up any results of a task with a certain ID when being restarted, even when explicitly restarted by the user. If that’s not what you want, you can make a call to Task.cancelAll() in the key handler for the ‘back’ key. That way you can ensure that all tasks (or their results) are discarded when explicitly exiting the activity. You can also cancel a single task using task.cancel(). A canceled task will never post any result or error data back to the caller.

How it works

Internally, task state is maintained in a static hash mapping callers to their list of tasks. This assures that tasks are kept in memory as long as the Task class itself (or until they terminate of course). The Task class does all the locking, state updates and callback invocations for us; we can even create a ProgressDialog and assign it to a Task using Task.setProgressDialog(). The dialog will then automatically be displayed when the task starts running, and will close when the task finishes. A task (or more precisely: a list of tasks) is bound to its caller (the calling activity or service) by the caller’s ComponentName. That means, you can think of tasks being associated to a calling class, rather than a calling object. The task class will take care of removing tasks that finished and which have been posted back to the caller, but it will preserve all completed (uncanceled) tasks until the caller claims its results, in case the caller wasn’t reachable while the task was finishing.

You can download the Task module for free here.

March 15, 2009

Understanding Android Themes and Styles

Filed under: Mobile Devices, Software Development & Programming — Tags: , , — Matthias @ 8:10 pm

I don’t know how many hours I’ve spent struggling with Android’s theme engine, trying to figure out — mostly by trial and error — how styles are applied and how to properly define them (let’s be honest: the documentation on styles in Android is a bit lacking). I thought it may be worth sharing what I’ve found out so far, in order to save my fellow Android developers from baldness due to ripped out hair (I sure lost some). This is a work in progress (so is Android), and some information may be inaccurate. If you find anything that you think is wrong or unclear, please let me know by dropping a line in the comments section. On another note, I assume that you have read the reference documentation on Android styles, if not, you should do that now.

What are Android styles?

A style in Android is a collection of attribute/value pairs applied to a view, an Activity or the entire application (which means, all Activities in your application). Styles for Activities are called themes, but do not get confused: they are syntactically equivalent to styles (because they are styles), they merely have a different scope. At this point I want to clarify something upfront: Themes or styles in Android have nothing to do with user styles known from applications such as, say, Firefox. Android users can not change the looks of Android applications by downloading themes from the Market or creating their own (yet). Android themes are of interest for developers only, think of them as syntactic sugar, a way of making your application’s view code more DRY.

How do I define custom styles?

Let’s look into a simple theme definition (stored in res/values/styles.xml):

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="MyTheme" parent="android:Theme.Light">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowBackground">@color/translucent_blue</item>
    <item name="android:listViewStyle">@style/MyListView</item>
  </style>

  <style name="MyListView" parent="@android:style/Widget.ListView">
    <item name="android:listSelector">@drawable/list_selector</item>
  </style>
</resources>

First, we declare a new theme called MyTheme, which inherits from another theme called Theme.Light in the android namespace (specified by the ‘parent’ attribute). This means that all styles we do not explicitly specify in our custom theme will be merged down from the definition of android:Theme.Light (the curious among you may want to download the Android source code and go to frameworks/base/core/res/res/values to see how it is defined; all stock styles are defined in themes.xml and styles.xml in that folder).

In our theme definition, we also set some custom styles using the ‘item’ element. We set the windowNoTitle attribute to true, so all activities that use our theme won’t have a title bar. We also set the window background color to a custom color called ‘translucent_blue’; this is a resource reference (indicated by the @ symbol) to a color definition in values/colors.xml. We could also have passed a reference to a drawable here, or have provided a hex color value directly. Finally, we set the default style for ListView widgets to a custom style called MyListView. Its style definition follows the exact same structure as the MyTheme definition, just that this time it is not a theme, but simply a style that can be applied to ListView objects. It inherits from the default styles for ListView but replaces the default selector image with a custom drawable.

There are two important things to understand here. First, those two style definitions are completely independent of each other (well, apart from the fact that we reference MyListView in MyTheme of course). This means, that if I remove the reference to MyListView from MyTheme, I can still use that style by applying it manually to a ListView declaration in a layout file. Think of styles simply as a bunch of attributes and values you would have otherwise typed directly into your view definition, so instead of writing

<ListView android:listSelector="@drawable/list_selector" />

we write

<ListView style="@style/MyListView" />

or better yet, we let this style be applied automatically to all ListView widgets by setting it in a theme definition (as seen above). (Note the missing ‘android:’ namespace reference here; this is intentional, the ‘style’ attribute is not defined in the ‘android’ namespace. You will get an error if you try to set a style using ‘android:style’, there is no such attribute.)

That way we never have to touch the ListView definition anymore; we can do all its styling from a single point, the style sheet. This helps in leaving the code for defining structure in your layouts, while leaving the code for defining appearance in your style sheets — a good example for separation of concerns. More importantly, your style definitions can be reused, which is particularly useful if styles are shared between several views.

The other important thing to understand is that styles do not have any type semantics. When we create a style called MyListView which inherits from Widget.ListView, then the intuition is that we are creating a style that is only supposed to apply to ListView objects. That’s not entirely correct though. There is no mechanism that will check whether we indeed apply that style to a ListView or even prevent us from applying it to an entirely different view type. It just so happens that Widget.ListView defines some attributes that only make sense when being applied to a ListView (such as listDivider), this doesn’t stop us, however, from creating a style that totally makes sense for any widget type (maybe because it only uses attributes defined in the View class, the parent class of all views). The bottom line is that you have to figure out yourself whether a style you define makes sense when you apply it to a view. Android will not do any sanity checks for you. In the worst case, the targeted view will expose odd behavior when being rendered, but more probably nothing will happen at all.

So what can I style, and from what can I inherit?

To get going with styles, it’s of course important to know two things:

  1. what’s there to be styled, and
  2. what styles are already there to inherit from

The easy answer is: Anything in android.R.styleable can be used inside a style body as a subject for styling (using the item tag), while anything in android.R.style can be used as parent styles to inherit from. So, to stick with the ListView example style, the android:listSelector style item can be found in android.R.styleable, while android:style/Widget.ListView is defined in android.R.style. Those two files are therefore what you want to turn your attention to first when defining custom styles. You should generally always inherit all default style items first, and then overwrite them one by one with your custom items.

That’s basically already it, a simple yet powerful style framework if used correctly!

Useful Tidbits

Text Appearance

Did you find yourself defining text appearance like font size or text color over and over again in your layouts? Don’t do that, use text appearances instead. Text appearances are styles, too, and Android already defines some for you which you can override (they are, of course, defined in R.style). This helps tremendously in keeping your view code DRY, and encourages you to get some structure into your different font styles used throughout your app by grouping them into styles you can reference and reuse. If, for example, you want to change the default text appearance in your app, simply define a custom text appearance in your stylesheet and set it as the default in your theme:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="MyTheme" parent="android:Theme.Light">
    <item name="android:textAppearance">@style/MyDefaultTextAppearance</item>
  </style>

  <style name="MyDefaultTextAppearance" parent="@android:style/TextAppearance">
    <item name="android:textSize">12sp</item>
    <item name="android:textColor">#333</item>
    <item name="android:textStyle">bold</item>
  </style>
</resources>

Make yourself familiar with all the text appearances Android already defines, and customize them for your application as you see fit.

Colors

Avoid setting color values directly in layouts or styles. Define them in a color resource file instead, and only use references to those color values from your layouts and styles. This helps in isolating them from the rest of your view code and makes your styles less brittle if you should decide to change a color afterwards. For simple, non-stateful colors, you can simply create a colors.xml file in res/values:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <color name="default_text_color">#FFEAEAEA</color>
    ...
</resources>

Often, however, colors can be more complex. If, for instance, you use a custom list selector image, it may happen that list text is readable when not selected, but becomes difficult or impossible to read when the custom selector is drawn (e.g. because the coloring is too similar). In that case, you need a ColorStateList, which you can use to automatically change colors for the view it’s applied to, based on that view’s state. Start by creating a new file, e.g. ‘stateful_text_color.xml’ in your res/colors directory. The resource root is ‘selector’, which is what you always use when creating resources that change with a view’s state:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_enabled="false" android:color="#333" />
  <item android:state_window_focused="false" android:color="#CCC" />
  <item android:state_pressed="true" android:color="#FFF" />
  <item android:state_selected="true" android:color="#FFF" />
  <item android:color="@color/default_text_color" /> <!-- not selected -->
</selector>

You get the idea. You can set this stateful color resource like any other color, it’s simply defined in a different way.

Also keep in mind that there are already color definitions shipped with Android. The most useful of them is probably android:color/transparent, which corresponds to the color #00000000. The first 8 bit, i.e. the first two hex digits, represent the alpha channel which is used to define opacity. A value of zero means zero opacity, or 100% transparency; the remaining color bits are therefore of no relevance, because they will be invisible. You can then turn the background of your views transparent by doing something like:

<style name="MyListView" parent="@android:style/Widget.ListView">
  <item name="android:background">@android:color/transparent</item>
</style>

That’s it for now. If I find out more about styles in Android, I’ll update this post accordingly. Feel free to contribute in the comments section, too.

February 9, 2009

Latest Android Update Introduces Ability To Change Locale

Filed under: Hardware & Technology, Mobile Devices — Matthias @ 9:58 am

My G1 just updated to the new 1.1 firmware. Unfortunately, Google doesn’t seem to publish details on Android updates, but I noticed two major changes:

  1. In “About phone” there is now a “System updates” tab which allows you to manually check for updates
  2. Support for voice search (with and without geo-sensitivity)
  3. The setting that only controlled text and writing options is now called “Locale & text” and allows you to set your phone to a different locale

The latter change was a much requested feature, however, it doesn’t seem to work properly with my phone. I use a German SIM card, but still, I cannot set the locale to something other than “English”. This is a bit frustrating, because e.g. phone numbers are formatted differently in Germany than they are in the U.S., so dialing numbers on my G1 feel a bit awkward. (On a side note, it is interesting to notice that the Browser application defaults to google.de on my phone, i.e. to the German version of Google search.)

Does anyone experience similar problems with not being able to change the locale? I suspect it may be related to the origin of my phone (I received it from Google rather than buying it in a local store).

October 17, 2008

Talking to Web Servers via HTTP in Android 1.0

Filed under: Mobile Devices, Software Development & Programming — Tags: , , , — Matthias @ 9:08 pm

If you have worked with Google Android prior to the 1.0 release, you probably have noticed that Google has upgraded the Apache HttpClient module in Android 1.0 from 3.x to a recent alpha release of version 4, which is a complete rewrite and brings with it a host of API changes. Unfortunately, the alpha version included in Android 1.0 is both terribly documented and lacking an important feature: supporting multipart requests using the multipart/form-data MIME type. Sending GET requests has changed significantly, too. Where you were formerly be able to add request parameters to a GetMethod object, you now will have to build a query string on your own and initialize an HttpGet object with it.

Here is how HTTP GET works in Android 1.0:

HttpClient httpClient = new DefaultHttpClient();

StringBuilder uriBuilder = new StringBuilder(SERVICE_ENDPOINT);
uriBuilder.append("?param0=" + param0);
uriBuilder.append("&param1=" + param1);
uriBuilder.append("&paramN=" + paramN);

HttpGet request = new HttpGet(uriBuilder.toString());
HttpResponse response = httpClient.execute(request);

int status = response.getStatusLine().getStatusCode();

// we assume that the response body contains the error message
if (status != HttpStatus.SC_OK) {
    ByteArrayOutputStream ostream = new ByteArrayOutputStream();
    response.getEntity().writeTo(ostream);
    Log.e("HTTP CLIENT", ostream.toString()));
} else {
    InputStream content = response.getEntity().getContent();
    // <consume response>
    content.close(); // this will also close the connection
}

Sending a multipart request first involves some environmental setup, since the required libraries are not bundled with Android 1.0. First, go to the Apache HttpClient download page and download the distribution called “Binary with dependencies”. In that package you’ll find two libraries: apache-mime4j-0.4.jar and httpmime-4.0-beta1.jar. Copy these files to e.g. the lib/ folder of your Android project and add them to the build path. You can now use a MultipartEntity to send multipart POSTs as such:

HttpClient httpClient = new DefaultHttpClient();

HttpPost request = new HttpPost(SERVICE_ENDPOINT);
MultipartEntity entity = new MultipartEntity();
entity.addPart("param0", new StringBody("value0"));
entity.addPart("param1", new StringBody(Double.toString(1.0)));
entity.addPart("paramN", new FileBody(new File("/bar/baz")));
request.setEntity(entity);

HttpResponse response = httpClient.execute(request);
int status = response.getStatusLine().getStatusCode();

if (status != HttpStatus.SC_OK) {
    // see above   
} else {
    // see above
}

And that’s that. I assume Google has included this early build of HttpClient 4 in Android 1.0 so that they will remain API-stable for the years to come, without being stuck with a legacy HTTP component.

References:
http://groups.google.com/group/android-developers/browse_frm/thread/e4230ed22c196772
http://wiki.apache.org/HttpComponents/HttpCoreTutorial
http://hc.apache.org/httpcomponents-client/examples.html

August 15, 2008

Handling Long Running Operations In Google Android

Filed under: Mobile Devices, Software Development & Programming — Tags: , , — Matthias @ 12:27 pm

User interface responsiveness is a crucial thing for all applications that require user interaction, but maybe even more so when programming for mobile handsets. Google’s Android programming environment unfortunately does not provide any mechanism for handling operations that may require a fair amount of time to complete, but which in itself are not meant to be implemented as Android Services. An example for this would be network I/O in an Activity, such as posting data to (or retrieving data from) a remote Web server. Because the Android runtime will terminate any Activity that does not respond within a couple of seconds, it is impossible (and simply a bad idea anyway) to perform such tasks from within the UI main thread.

That being said, I have come up with a generic class that handles long running operations by spawning a separate thread and passing back any result or error data to the main thread using a callback mechanism. An animated progress dialog will be displayed while the operation is running. That way the user is kept informed about any program activity that may take some time to complete.

The class can be used as follows:

public class MyActivity implements LongRunningActionCallback<Void> {

    private LongRunningActionDispatcher<Void> dispatcher;

    private void startLongRunningOperation() {
        // the first argument is a reference to the current Context, in this
        // case the current Activity. The second argument is a reference to
        // the object implementing the callback method.
        this.dispatcher = new LongRunningActionDispatcher<Void>(this, this);
        dispatcher.startLongRunningAction(new Callable<Void>() {
            public Void call() throws Exception {
                // perform your actions that take a long time
                return null;
            }
        }, "Dialog Title", "Dialog message");
    }

    // the callback
    public void onLongRunningActionFinished(Void result, Exception error) {
        if (error != null) {
            // handle error
        } else {
            // success, work with the result, if any
        }
    }
}

This will spawn a progress dialog (not indicating any actual progress in percentage, it’s just a “busy” dialog) with the given title and message. If an exception occurred in the Callable you provided, it will be passed as the error argument to the callback, so you should always check whether it’s non-null.

Below are the source codes for both LongRunningActionDispatcher and LongRunningActionCallback.

import java.util.concurrent.Callable;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.Handler;
import android.util.Log;

/**
 * Use this class if you need to dispatch expensive (long running) operations
 * from your Activity. The long running operation is provided to
 * {@link startLongRunningAction} as a {@link Callable}. The result of the
 * operation and any potential exception that occurred during the call are
 * passed to {@link LongRunningActionCallback.onLongRunningActionFinished},
 * which will be called on successful or unsuccessful completion of the
 * Callable.
 *
 * LICENSE STATEMENT (DO NOT REMOVE):
 * This code is in the public domain. You may use, alter, and redistribute it
 * free of any charges or obligations, with the following exceptions:
 * 1. You are not allowed to remove the statement naming the original author.
 * 2. You are not allowed to remove this license statement.
 *
 * @author Matthias Kaeppler
 */
public final class LongRunningActionDispatcher<ResultType> {

    private Context context;

    private LongRunningActionCallback<ResultType> callback;

    /**
     * A progress dialog shown during long-lasting operations
     */
    private ProgressDialog progressDialog;

    private Handler finishedHandler = new Handler();

    public LongRunningActionDispatcher(Context context,
            LongRunningActionCallback<ResultType> callback) {
        this.context = context;
        this.callback = callback;
    }

    /**
     * Invoke this method to start long running operations which may block your
     * activity and therefore the main UI thread. A progress dialog will be
     * shown while the operation is executing.
     *
     * @param callable
     *            The callable
     * @param progressDialogTitle
     *            The progress dialog title
     * @param progressDialogMessage
     *            The progress dialog message
     */
    public void startLongRunningAction(final Callable<ResultType> callable,
            String progressDialogTitle, String progressDialogMessage) {

        progressDialog = ProgressDialog.show(context, progressDialogTitle,
                progressDialogMessage, true, false);

        new Thread(new Runnable() {

            public void run() {
                ResultType result = null;
                Exception error = null;
                try {
                    result = callable.call();
                } catch (Exception e) {
                    Log.e("ERROR", e.getMessage());
                    error = e;
                }

                final ResultType finalResult = result;
                final Exception finalError = error;
                finishedHandler.post(new Runnable() {

                    public void run() {
                        onLongRunningActionFinished(finalResult, finalError);
                    }
                });
            }
        }).start();
    }

    private void onLongRunningActionFinished(ResultType result, Exception error) {
        progressDialog.dismiss();
        callback.onLongRunningActionFinished(result, error);
    }
}
/**
 * LICENSE STATEMENT (DO NOT REMOVE):
 * This code is in the public domain. You may use, alter, and redistribute it
 * free of any charges or obligations, with the following exceptions:
 * 1. You are not allowed to remove the statement naming the original author.
 * 2. You are not allowed to remove this license statement.
 *
 * @author Matthias Kaeppler
 */
public interface LongRunningActionCallback<ResultType> {

    /**
     * Called when the callable provided to
     * {@link LongRunningActionDispatcher.startLongRunningAction} completes.
     *
     * @param <ResultType>
     *            The result type of callable.call()
     * @param result
     *            Whatever the callable returns if it completes successfully, or
     *            null if an exception was thrown
     * @param error
     *            Whatever the callable throws if it executes in error, or null
     *            if it completed successfully
     */
    void onLongRunningActionFinished(ResultType result, Exception error);
}

July 17, 2008

Nielsen Survey shows: Mobile Web adoption is picking up the pace

Filed under: Mobile Devices — Tags: — Matthias @ 2:15 pm

I have to admit I am currently somewhat hyped about the mobile Web, particularly in face of its opportunities for mobile social media. A recent survey by Nielsen Mobile shows that especially in the U.S. the adoption of the mobile Web experiences rapid growth:

We believe mobile Internet has reached a critical mass as an advertising medium in the US. As of May 2008, there were 40 million active users of the mobile Internet in the US, with individual sites that attract millions of unique users.

Source: Nielsen Mobile

Since my thesis focuses on mobile social media, I can hardly wait to see similar growth (and price drops) here in Germany — fixed price subscription plans are still too expensive.

January 24, 2008

Cowon iAudio D2 – PMP With Two Faces

Filed under: Hardware & Technology, Mobile Devices — Tags: , , , , , , , , — Matthias @ 10:23 am

I am currently in Tokyo for a couple of months and I commute five days a week between Soka-shi in the Saitama prefecture to Bunkyo-ku in Tokyo. In total, that’s a one hour trip two times per day, which may not seem that big of an issue to most people, but for my part, I am simply not used to it and it is really becoming a chore.

Obviously, it was time to upgrade my mobile gear and let go of my iPod Nano, which I learned to hate in its few months of use. Sound quality and headphones are almost ridiculously bad for a device with a 180€ price tag, I never got used to the navigation wheel, it operates very fuzzy and unprecise and the display is small, low-res and everything but rich in color. My biggest gripe however with the Nano — and iPods in general — is Apple’s inability (refusal maybe) to provide proper Linux support for their devices. Their iTunes software has still not been ported to Linux, and most probably never will. There are open-source solutions like GTKPod, Floola and various iPod plugins for popular Linux media players like Rhythmbox, Banshee or Exaile, but I have used them all, and most of them are buggy, difficult to use or do not support newer iPods. Being an open-source aficionado and full-time Linux user myself, I have to face the truth: iPods simply do not fit into my setup. I admit it though, the iPod Touch looks sexy and I thought about buying it. I would have loved to have Wi-Fi on my PMP. But, considering these points and the fact that almost everyone between 10 and 30 is running around with an iPod these days, my urge to buy one has somewhat declined — or, as some user on the head-fi.org forums put it: “It is my personal opinion that owning a soul and owning an apple product are incompatible concepts”. Although my attitude towards Apple products ain’t that radical, I can definitely see where he is coming from.

Long story short, I went with Cowon’s iAudio D2, the 4GB version, in white. South-Korea based Cowon has made itself a name for building portable audio players with excellent sound quality, and best of all, which can be used with Linux, because they do not use a database model that can only be updated by means of a proprietary software (such as iTunes or Sony’s equivalent for their Walkman players). Instead, the D2 is recognized by the system as a USB mass storage device and you can simply drag-and-drop your music and video files onto the respective folders. Easy and simple. For Windows users, Cowon also ships their JetShell and JetAudio software for transferring and converting media files.

The device is small and handy (though maybe a bit thick — check this site to see how its size compares to an iPod Touch) and sports a high resolution, color rich display which is operated by touch. In fact, the only buttons on the D2 are the power and hold button (which are incorporated into a single snap-slider, very cool), a menu or “M” button (which can be configured to do different things), and two buttons for volume control. Navigation using the touch screen is responsive and for most parts straight forward. The default user interface already looks really sleek, but if you do not like it: it’s skinnable. For those people whose fingers aren’t slim anough to hit the (sometimes really small) on-screen buttons, Cowon also packs a plastic pointer with the D2.

Sound quality is great, it’s lightyears ahead of an iPod. Moreover, the D2 has the most capable equalizer I have ever seen on a PMP, it lets you adjust an almost ridiculous amount of options. The earphones bundled with the D2 are decent, but maybe not great. Still, much better than the ones coming with a Nano. Video playback is fluent, and the 16 Million colors display is crisp, which — despite its small size (2.5 inch at 320×240 pixels) — lets you read smaller text as well.

Concerning audio formats, the player supports a much wider range of codecs than most other players I have seen to date, including OGG, which will make many Linux users happy (at the time of this writing, OGG support is buggy on the D2 as some OGG tags are not properly read by the player; playback support is there however). For the video support, the D2 unfortunately doesn’t shine as bright. In fact, this is one of my biggest gripes with the D2: It doesn’t play videos encoded with the AAC audio codec, the format employed by Apple which almost every website that syndicates podcasts uses. Instead, the D2 can only play videos with MP3 encoded audio. This is extremely annoying, as you have to fall back to a video transcoder in order to play back video podcasts downloaded from the internet. There is also some confusion about the actual video codec and container format (I am no expert on this, so please anyone correct me if I’m wrong): The player is often tagged as an MP3/MP4 player, which is supposed to indicate that it can play back MPEG-4 encoded video (it supports the XviD codec, I am not sure about other MPEG-4 codecs). Technically, this is wrong however, because MP4 does not refer to the video codec, but the multimedia container format, and the D2 does not use MP4 here, but AVI (the format introduced by Microsoft in the `90s). Although the specs are silent about the supported container formats, my D2 won`t even display video files ending in .mp4, but it does display all files ending in .avi.

Another extremely annoying issue I am having with my D2 is its seemingly buggy support for ID3v2 tags. Although my MP3s are properly tagged, they always show up in the Music Library in wrong order, that means, not sorted by track number. For albums where order matters, like DJ mixes or audio books, this is a show-stopper, as there is no support to manually sort tracks on the D2. As a fallback, one has to go through the D2′s file browser instead. I seriously hope this will be fixed with a future firmware update.

To draw a conclusion, I think the D2 is a somewhat two-faced PMP. It does so many things right, like providing OGG support for Linux users, but then again, the support is buggy or incomplete. Then it provides lots of audio codecs, which makes it very versatile in that department, but for video, it only supports a format that almost nobody on the WWW uses to distribute podcasts — the killer application for portable media players! Concerning the user interface and functionality, light and shadow continue to co-exist on the D2: There are two (!) different calculator programs (gimme a break), but I can’t even do simple things like sorting my tracks or create playlists.

While I can still recommend the D2, if even for the mere lack of decent competition in the deserted lands of Linux-compatible PMPs, these points just make me pull out my hair and scream: “It would have been so simple, why, Cowon, why?!”.


Find below some reference and software proposals on how to operate the D2 under Linux.

Podcast management: GPodder — a very decent podcatcher for Linux (GTK-based)

Video conversion: iRiverter* — get the D2 device profile here

* some Ubuntu Linux users (including me) had problems running iRiverter. If you get an exception about a missing SWT library, try following this proposed solution, which fixed the problem for me.

UPDATE 2008-01-26: Modified section about video and codec support

December 30, 2007

Ubuntu Linux on a Samsung R55 Notebook

Filed under: Hardware & Technology, Linux & Open Source — Tags: , , , — Matthias @ 1:24 pm

In an attempt of shameless self-promotion, I’d like to point out my website covering the installation and potential issues of running Ubuntu Linux on Samsung’s R55 notebook series.

http://www.infodump.de/samsung-r55-linux

It focuses on an older version of Ubuntu, but I will update it once the next LTS release of Ubuntu hits the server somewhere around April 2008.

The Shocking Blue Green Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 37 other followers