Fabrizio Giudici is a Senior Java Architect with a long Java experience in the industrial field. He runs Tidalwave, his own consultancy company, and has contributed to Java success stories in a number of fields, including Formula One. Fabrizio often appears as a speaker at international Java conferences such as JavaOne and Devoxx and is member of JUG Milano and the NetBeans Dream Team. Fabrizio is a DZone MVB and is not an employee of DZone and has posted 67 posts at DZone. You can read more from them at their website. View Full User Profile

A Simple Control Flow Facility For Android Activities

05.16.2010
| 14327 views |
  • submit to reddit

How does one navigate through Activities in Android? By means of an asynchronous message-passing facility called "Intent". Basically, one Activity creates and sends a message to the runtime, which reacts by bringing on the screen the recipient Activity of the message, that gets activated.

Messages can be based on a sort of "publish and subscribe" pattern (they carry a "topic" and the proper Activity is found as it declared to be competent about the topic in the application manifest):

Intent intent = new Intent("topic");
// eventually put extra information into the intent
startActivity(intent);

Alternatively it is possible to explicitly specify the recipient by referring its class (in this case we have a "point to point" messaging system):

Intent intent = new Intent();
intent.setClass(..., NextActivity.class);
// eventually put extra information into the intent
startActivity(intent);

A special kind of message is generated by calling the finish() method, which notifies that an Activity terminated its task, so the control is returned to the sender of the message.

As a plus, Android keeps track of the flow and implements a stack of the recently visited Activities, so the "back" button usually works automatically without needing further code; the "finish" message flushes the stack up to the caller point.

I'm a big fan of the "publish and subscribe" pattern because it does a great job in decoupling the various part of a design. In Android, the mechanism is very powerful because the various Activities needn't to be part of the same application: it's very easy to have multiple applications to cooperate. For instance, sending an Intent with a pre-defined topic can bring up the email client, or the phone contact list, etc.

Unfortunately, often you need the "point to point" variant of messaging when you operate inside an application as you require a specific sequences of Activities, as in my introductory example.

Now, the "point to point" pattern is very coupling because the originator needs to know the recipient. In other words, PickTaxonActivity and TaxonBrowserActivity need to know which is the next Activity to start: CountAndGenderActivity (flow #1) or FactShetActivity (flow #2). If I wanted to reuse them in further scenarios, I would have more coupling and complicated code, with PickTaxonActivity and TaxonBrowserActivity depending on a number of other Activities, while it should be really the opposite. This is a sign of a bad distribution of roles & responsibilities: Activities should only focus on their own task and know nothing of what happens after.

Who should be in charge of defining the sequence? A possible candidate could be the initial ObservationsActivity as it knows which command has been invoked by the user, thus it knows the whole sequence of steps to walk through. So, in a first time I thought of an approach where each Activity, when it completes, always sends a "finish" message, so it immediately returns to ObservationsActivity; this class would implement the logic for finding the next step and starting the related Activity.

Unfortunately, in this way you completely loose the stack-based back button implementation provided by Android, which is a big pitfall. In order to keep it, each Activity, when it completes, must keep on sending messages forward.

Published at DZone with permission of Fabrizio Giudici, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Casper Bang replied on Mon, 2010/05/17 - 11:52am

That's a very nice pattern, kind of a fluent-interface version of Struts for Android. :) Does this work with Intent filters, i.e. can an Activity have multiple implementations but let the user pick the preferred one? Say I want to write a "plugin" i.e. TaxonByIdActivity for the hardcore birdwatchers who memorized taxonomy ID's?

Fabrizio Giudici replied on Mon, 2010/05/17 - 1:33pm

I've got some extra code that works with Intents, but it's experimental (and probably unneeded for my current requirements). The pattern was born having in mind to solve the problem of direct coupling, but clearly the smart things it does is decoupling navigation decisions - which could end up in Intents as well.

I'm thinking of a similar things that you described, i.e. the capability of extending blueBill with "plugins" that would be delivered as extra application; for instance, a bunch of media providers, that would provide multiple documents available in the internet (or on the local storage) about a certain bird species. This would work with Intents, of course - both letting the user to pick the desired one, or even calling sequentially all the found things and aggregating the results. I've got a tough week, but I'll probably work on that the next weekend.

Fabrizio Giudici replied on Mon, 2010/05/17 - 1:35pm

PS Another thing that I'll soon study is to try to abstract it from Android. In this way, it could be used e.g. for an implementation in JME or JavaFX Mobile - of course, you don't have Activities in those contexts, but you could as well face with a sequence of "screens".

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.