The Pause Caveat
There is one hiccup with using Intent objects to pass arbitrary messages around: it only works when the receiver is active. To quote from the documentation for BroadcastReceiver
:
If registering a receiver in your Activity.onResume() implementation, you should unregister it in Activity.onPause(). (You won’t receive intents when paused, and this will cut down on unnecessary system overhead). Do not unregister in Activity.onSaveInstanceState(), because this won’t be called if the user moves back in the history stack.
Hence, you can only really use the Intent framework as an arbitrary message bus if:
• Your receiver does not care if it misses messages because it was not active.
• You provide some means of getting the receiver “caught up” on messages it missed while it was inactive.
In Chapters 30 and 31 on creating and using services, you will see an example of the former condition, where the receiver (service client) will use Intent-based messages when they are available but does not need them if the client is not active.
CHAPTER 24
Launching Activities and Sub-Activities
The theory behind the Android UI architecture is that developers should decompose their application into distinct activities, each implemented as an Activity
, each reachable via Intents
, with one “main” activity being the one launched by the Android launcher. For example, a calendar application could have activities for viewing the calendar, viewing a single event, editing an event (including adding a new one), and so forth.
This, of course, implies that one of your activities has the means to start up another activity. For example, if somebody clicks on an event from the view-calendar activity, you might want to show the view-event activity for that event. This means that, somehow, you need to be able to cause the view-event activity to launch and show a specific event (the one the user clicked upon).
This can be further broken down into two scenarios:
• You know what activity you want to launch, probably because it is another activity in your own application.
• You have a content Uri
to… something, and you want your users to be able to do… something with it, but you do not know up front what the options are.
This chapter covers the first scenario; the next chapter handles the second.
Peers and Subs
One key question you need to answer when you decide to launch an activity is, does your activity need to know when the launched activity ends?
For example, suppose you want to spawn an activity to collect authentication information for some Web service you are connecting to — maybe you need to authenticate with OpenID [30] in order to use an OAuth[31] service. In this case, your main activity will need to know when the authentication is complete so it can start to use the Web service.
In this case the launched activity is clearly subordinate to the launching activity. Therefore you probably want to launch the child as a sub-activity, which means your activity will be notified when the child activity is complete.
On the other hand, imagine an email application in Android. When the user elects to view an attachment, neither you nor the user necessarily expects the main activity to know when the user is done viewing that attachment.
In this scenario, the launched activity is more a peer of your activity, so you probably want to launch the “child” just as a regular activity. Your activity will not be informed when the “child” is done, but, then again, your activity really doesn’t need to know.
Start ’Em Up
The two requirements for starting an activity are an Intent and your choice of how to start it up.
Make an Intent
As discussed in Chapter 1, Intent
s encapsulate a request, made to Android, for some activity or other Intent
receiver to do something.
If the activity you intend to launch is one of your own, you may find it simplest to create an explicit Intent
, naming the component you wish to launch. For example, from within your activity, you could create an Intent
like this:
new Intent(this, HelpActivity.class);
This would stipulate that you wanted to launch the HelpActivity
. This activity would need to be named in your AndroidManifest.xml
file, though not necessarily with any Intent
filter, since you are trying to request it directly.
Or you could put together an Intent
for some Uri
, requesting a particular action:
Uri uri = Uri.parse('geo:' + lat.toString() + ',' + lon.toString());
Intent i = new Intent(Intent.ACTION_VIEW, uri);
Here, given that we have the latitude and longitude of some position (lat
and lon
, respectively) of type Double
, we construct a geo
scheme Uri
and create an Intent
requesting to view this Uri(ACTION_VIEW)
.
Make the Call
Once you have your Intent
, you need to pass it to Android and get the child activity to