THE ACTIVITY CLASS
WATCHING THE ACTIVITY IN ACTION
The activity, if used correctly, is an object that specifically controls a single screen.
Let’s talk about this mythical activity in terms of a real-world RSS news feed reader as a case study that can quickly explain what pages of theory would often miss. A developer typically uses one activity to list all feeds to which a user has subscribed. When a user taps a feed, the developer uses a second activity to display a list of available articles for that particular news feed. Lastly, when a user clicks a particular story, the developer uses a third activity to display article details.
It’s easy to see how activities fill a certain role (subscription list, article list, article detail). At the same time, the activities are general, in that the article list should be able to display a list of articles from any RSS feed, and the article details activity should show the details from any article found through an RSS reader.
THE ACTIVITY CLASS 23
ptg7794906 IMPLEMENTING YOUR OWN ACTIVITY
In most cases, the best way to understand something is to use it. With that in mind, let’s add a new activity to the project you created in Chapter 1. This will explain how the activity works, its lifecycle, and what you need to know while working with it. Here are the general steps you’ll need to follow:
1. Add an entry for the new activity into your manifest.
2. Create a new class that extends the Activity class.
3. Create a new file containing the XML layout instructions for this new activ-ity, and add a new string literal for the layout to display (don’t worry, this sounds a lot harder than it actually is).
4. When all the files are in place, you’ll need to actually launch this new activ-ity from your existing one.
THE MOST BASIC OF ACTIVITIES
In its simplest form, an activity is an object that extends the Activity class. It should, but doesn’t have to, implement the onCreate method. Here’s what your activity looks like by default when you create a new project:
public class MyActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main);
} }
In this code, the device calls the onCreate method as the activity is starting.
onCreate tells the UI system that the setContentView method specifies the main layout file for this activity. Each activity may have one and only one content view,
ptg7794906 so once you set it, it can’t be changed. This is how the Android SDK forces you to
use a new activity for each screen, because each time you want to change your root content view, you’ll need a different activity.
TELLING ANDROID ABOUT YOUR FRIENDLY NEW ACTIVITY
The Android system needs to know where to find your new activity when it comes time to load and launch it.
1. Open up the AndroidManifest.xml file in Eclipse.
2. Add the following line inside the <application> tag and directly after the
</activity> closing tag of the previous declaration:
<activity android:name=”.NewActivity”/>
This little line tells the system where to find the new activity in your appli-cation package. In the case of my demo, the class loader knows to look for the activity at com.haseman.peachPit.NewActivity.
Next, you’ll need to put a file there for it to find.
CREATING THE NEWACTIVITY CLASS
There are several ways to create a new activity, but here is the easiest way to do it in Eclipse.
1. Right-click (or Control-click) the package name you’ve chosen (mine is com.haseman.peachPit).
2. Select New, then select Class.
3. Give the class a name in the dialog.
A name is enough to create a new file. The file will be saved in your main package under the name you specified. In my demo, it is in my project under src/com/haseman/peachPit/NewActivity.java.
Now that you have a class that extends an object, you’ll need to switch it over to extend an activity.
THE ACTIVITY CLASS 25
ptg7794906 4. Make the following highlighted change to your code:
package com.haseman.peachPit;
import android.app.Activity;
import android.os.Bundle;
public class NewActivity extends Activity{
public void onCreate(Bundle icicle){
super.onCreate(icicle);
} }
Notice that this code looks very similar to what is already in your existing activity. Let’s make it a little bit different.
5. In the res/values/strings.xml file, add the following highlighted lines in the <resources> tag under the existing strings:
<resources>
<!—other strings are omitted here for brevity-->
<string name=”new_activity_text”>
Welcome to the New Activity!
</string>
</resources>
In these lines, you told Android that you want a new string with the name new_activity_text that can be accessed through Android’s resource man-ager. You’ll learn much more about the contents of the /values folder in later chapters. Next, you need to create a layout file for your new activity.
ptg7794906 CREATING A NEW SCREEN LAYOUT
Here’s how you create a new layout.
1. Create a new file named new_activity.xml inside the res/layout/ folder. It should sit next to the existing main.xml file (which is used by your existing activity). This new_activity.xml file should look almost exactly like main.xml, except you’ll need to add a reference to the string you just created.
2. Insert the highlighted line to create a reference to the string you just created.
3. Give this modified TextView an ID so your Java code can reference it (you’ll learn more about TextViews later; for now you should know that they’re Android views that show text on the screen):
<?xml version=”1.0” encoding=”utf-8”?>
I will devote Chapter 3 to resource management and user interface design, but for now just keep in mind that the @ prefix is how you tell Android you want to reference an ID, string, or drawable that is defined elsewhere as a resource.
Now that you have a new layout with its shiny new string, you’ll need to tell the NewActivity class that you want it to use this particular layout file.
THE ACTIVITY CLASS 27
ptg7794906 4. Add the following highlighted line to the onCreate method of your New
Activity class:
public void onCreate(Bundle icicle){
super.onCreate(icicle);
setContentView(R.layout.new_activity);
}
setContentView is the method in which you tell Android which XML file to display for your new activity. Now that you’ve created a new class, string, and layout file, it’s time to launch the activity and display your new view on the screen.
CATCHING KEYS
The simple way to launch your new activity is to have the user press the center key on his or her device. If your phone doesn’t have a center key, you can easily modify the following code to accept any key you like. To listen for key events, you’ll need to extend the original activity’s onKeyDown method. Keep in mind that this is a simple example case. Launching a new activity when the user presses a single key prob-ably isn’t a very common use case in practice, but it makes for a good and simple example. Most new activities are started when a user selects a list item, presses a button, or takes another action with the screen.
Here’s what your new version of onKeyDown should look like:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event){
if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER){
//Launch new Activity here!
return true;
}
return super.onKeyDown(keyCode, event);
}
ptg7794906 By declaring onKeyDown, you’re overriding the default key handler in order to
take action specific to your own activity. It’s always a good idea to pass the incoming key to the parent class’s version of the method if it’s not something your activity handles on its own.
Notice that when the keyCode matches the center button, you return true. This is how you tell the Android activity and views that the key has been correctly handled and shouldn’t be passed on to anyone else. Otherwise, you allow the activ-ity superclass to handle the key. This may not seem like a big deal now, but it will become much more important as your Android activities become more complex.
LAUNCHING THE ACTIVITY
Finally, it’s time to launch the new activity. This will start your brief foray into intents. Each new activity is started as the result of a new intent being dispatched into the system (which processes it and takes the appropriate action). In order to start the first activity, you’ll need a reference of your application context and the class object for your new activity. Let’s create the new intent first.
1. Place the following code into your onKeyDown key handling method:
Intent startIntent=new Intent(
this.getApplicationContext(), NewActivity.class);
You’re passing the new intent an application context and the class object of the activity that you would like to launch. This tells Android exactly where to look in the application package. There are many ways to create and interact with intents; this is, however, the simplest way to start up a new activity.
Once the intent is properly constructed, it’s simply a matter of telling the Android system that you’d like to start the new activity.
2. Put the following line into your key handling method:
startActivity(startIntent);
THE ACTIVITY CLASS 29
ptg7794906 Your onKeyDown handler should look like the following:
public boolean onKeyDown(int keyCode, KeyEvent event){
if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER){
Intent startIntent=new Intent(this, NewActivity.class);
startActivity(startIntent);
return true;
}
return super.onKeyDown(keyCode, event);
}
TRYING IT OUT
If you’re running Eclipse and you’ve been coding along with me, it should now be a simple matter of spinning up the emulator and installing your new activity (the steps for which you should remember from Chapter 1). Once your new application has launched, press the center key to see the results of all your labor (Figure 2.1).
Now that you know how to create and launch a new activity, it’s time to discuss how that process works. You’ll need to understand, for the purposes of UI layout and data management/retention later, what methods are called each time one of your activities makes its way onto, and off of, the screen.
FIGURE 2.1 Here is your new activity!
NOTE: Throughout this whole process, the original activity has never once had access to the instance of the new activity. Any information that might pass between these two activities must go through the intermediary intent. You’ll learn how this is done in the next section.
ptg7794906 GETTING INTENTS
Intents can take a myriad of forms.
You use them anytime you need to start an activity or service. Further, you’ll frequently use intents for system-wide communication. For example, you can receive notifications about power system changes by registering for a widely published intent. If one of your activities registers for an intent in the manifest (for example, com.haseman.peachPit.OhOhPickMe), then any applica-tion anywhere on the phone can, if you make your activity public, launch directly to your activity by calling
startActivity(new Intent(“com.haseman.peachPit.OhOhPickMe”));