Getting Splashy

You can download the packaged version of this splash screen example from the downloads section of www.apress.com if you want to use it as a starting point for your own Android application or you want to follow along in a more passive fashion. In this example, because it is your first, I will go through it in a series of small steps. I'll break down exactly what needs to be written, from adding a new image resource to modifying XML layout files. Down the road, examples will not parse out into such minute detail. This should be the only chapter that will read like a tutorial for beginners.

Adding the Image Resource

First you'll need a sample splash screen image. The "socially awkward" splash screen I've included is not going to win any awards, but it is a good poke at the rash of social networking applications that seem to keep cropping up in the mobile space right now.

To add this new resource, I've placed menu_background.jpg inside res/drawable. Make sure a new ID is added to R.java. It should look something like this:

public static final int menu background=0x7f020001;

This is now your means of loading and drawing the image from within your code. You'll return to this concept in the next chapter on user interaction.

Creating an XML Layout File

Now that you have an image resource, you can add it to your XML layout file. These files are kept in res/layout/, and you should currently have one called main.xml. Add a new XML file called splash.xml, and copy the contents of the main.xml file into it. Next, modify the file by removing the <Textview> tag and add an <imageView> tag that looks like the following:

<ImageView android:src="@drawable/menu background" android:layout width="fill parent"

android:layout height="fill parent"> </ImageView>

Using Android's XML layout objects is simple and straightforward. As I mentioned, files in the /res directories can be referenced with the @

symbol as shown earlier, for example, android:src="@drawable/menu_background". Further, layout_width and iayout_height dictate the size of the image view. Look to make sure your new layout file has been added to R.java. It should appear as follows:

public static final int splash=0x7f030001;

Drawing the Splash Screen

Now that your splash screen is defined, it's time to activate and paint it. Your existing Android activity is already drawing main.xml, so you'll shift to your new splash layout. To make the switch, change this code:

setContentView(R.layout.main);

in the method onCreate to this code:

setContentView(R.layout.splash);

Run the application, and watch your newly created splash screen come to life. If you've gotten errors thus far, check to make sure your names for everything match up. If the image isn't drawing, make sure it's been correctly placed in the res/drawable folder and that splash.xml refers to the correct name and file.

Timing Is Almost Everything

The splash screen is now rendering, but splash screens alone make for boring applications, so you'll need to move on to the main menu. You'll use a simple inline-defined thread to accomplish the timing. There are a few constants initialized before the thread that I've included. For the sake of completeness, I've included the entirety of the onCreate method. Code Listing 2-1 shows what mine looks like with the timing thread in place.

Code Listing 2-1. Timing the Splash Screen long m dwSplashTime = 3000; boolean m bPaused = false;

boolean m bSplashActive = true;

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

//Draw the splash screen setContentView(R.layout.splash);

//Very simple timer thread

Thread splashTimer = new Thread() {

while(m bSplashActive && ms < m dwSplashTime) {

sleep(100);

//Advance the timer only if we're running. if(!m bPaused) ms += 100;

//Advance to the next screen. startActivity(new Intent(

"com.google.app.splashy.CLEARSPLASH"));

catch(Exception e)

finally {

splashTimer.start();

At long last, you're getting into some Java code. This simple thread will run until the time counter exceeds m_dwSplashTime. Although there are other methods for implementing a timer, I like this one for two reasons:

■ It can be paused. The timer will advance only if the m_bPaused flag is false. As you'll see in a minute, it's easy to suspend the timer if your activity's onPause method is called. This is not always a requirement for a splash screen, but it is important for other timing-based operations.

■ Moving to the next screen is as simple as flipping the m_bSplashActive flag to false. Advancing to the next screen, if you implement it in this fashion, does not require you to make the move and then cancel a more traditional timer.

With this code in place, you should see the splash screen for as long as you set m_dwSplashTime in milliseconds. When that time is up or the user interrupts the splash screen with a key press, startActivity will be called (I'll explain this shortly). This function will move the user to what will become the main menu in the next chapter. finish closes down the splash activity so the user does not return to it when they press Back from the main menu. You'll need to implement an activity that accepts the clearsplash intent action. In the meantime, let's review a few other important activity methods you'll want to override.

Pause, Resume, Rinse, Repeat

Pausing the splash timer when your activity is suspended by an incoming call, SMS message, or other interruption is as easy as the following:

protected void onPause() {

super.onPause(); m bPaused = true;

As with most of these overridden methods, you'll need to invoke the superclass before doing anything else. If you review the timer thread, you'll see that the ms counter responsible for keeping track of time passed doesn't advance if m_bPaused is true. At this point, I'm sure you can guess what onResume will look like:

protected void onResume() {

super.onResume(); m bPaused = false;

No surprises here. When your application is resumed, the timer thread will resume adding time to the ms counter.

Basic Key Handling

Key handling within the activity is handled by overriding the onKeyDown method. We'll use this function to allow a user to cancel your fledgling splash screen. As you can see in the timer thread at the start of this section, you've set up an escape clause in the timer loop by the name of m_bSplashActive. To escape, you'll just override the onKeyDown method so that it flips the splash flag to false. Here's the code you'll need to add:

public boolean onKeyDown(int keyCode, KeyEvent event) {

//if we get any key, clear the splash screen super.onKeyDown(keyCode, event); m bSplashActive = false; return true;

Now, when the user hits any key, the screen will be advanced on the next trip through the timer loop.

ADDITIONAL EXERCISES

If you want to make this a fully functional splash screen, you'll need to add two elements. This gives me a great excuse to assign you some homework. Try to add two bits of functionality:

■ Allow the user to skip the splash screen only when clicking the OK or center key.

■ Make the Back key exit the application rather than putting it in the background.

As a hint, you'll want to look up the key-code mapping in the Android SDK documentation to accomplish these tasks.

Clear Intent

There's one more thing you'll need to do before you're done with the splash screen. I'm sure you're wondering about that startActivity method call earlier. This means it's time to talk briefly, in this limited context, about the intent. An intent is an object that functions as a communication event between two or more activities, content handlers, intent receivers, or services. In this case, you will call startActivity with the intent com.google.app.splashy.CLEARSPLASH. When startActivity is called, Android searches all its manifests for the node that has registered for the aforementioned clearsplash intent action. It just so happens that you'll add your own activity called MainMenu that will register for just such an intent.

To create what will become the main menu activity, add a new class to your existing source package called MainMenu. Next, make sure it extends the Activity class, implements onCreate, and calls setContentView on R.layout.main. At this point, you'll want to open AndroidManifest.xml and add a new activity element to it. After the

</activity> closing tag of the splash screen, you should insert the following:

<activity android:name=".MainMenu"

android:label="@string/app name"> <intent-filter>

<action android:name=

"com.google.app.splashy.CLEARSPLASH"/> <category android:name=

"android.intent.category.DEFAULT"/> </intent-filter> </activity>

Define the activity's name as .MainMenu. This will tell Android which Java class to load and run. Register, within the intent filter tag, for the com.apress.splash.CLEARSPLASH intent action. In reality, the name of the intent could be beef.funkporium.swizzle, and as long as the name is consistent between the startActivity call and the snippet of the Android manifest listed earlier, all the right things should continue to happen.

Running It

Running your application at this point should result, if you've paid attention thus far, in your splash screen being drawn for a few seconds, followed by your new main menu activity taking focus. It should also be impossible to get back to the splash screen once your application has advanced to the main menu. If you're having trouble, make sure your new main menu is listed in the manifest and in R.java. Also, make sure you're drawing the correct layout file within your new intent.

The Life Cycle of an Activity

The life cycle of an activity is covered extensively in the Google documentation. However, if I'm reviewing the nuts and bolts of what makes an activity, I cannot pass by this important information. At this point, with your splash screen, you should be ready to roll.

For explanation's sake, I've also added the following functions to the splash screen activity:

protected void onStop() {

super.onStop();

protected void onDestroy() {

super.onDestroy();

If you place breakpoints in all the functions within your new splash activity and run it in debug mode, you'll see the breakpoints hit in the following order:

1. onCreate

2. onStart

3. onResume

4. At this point, your activity is now running. Three seconds in, the timer thread will reach its end and call startActivity with the splash clearing intent. Next, it will call finish, which tells Android to shut down the splash screen activity.

5. onPause

6. onStop

7. onDestroy

This is the general life cycle of an activity from start to finish. You can find a much more comprehensive exposé on the life and times of an Android activity in Google's documentation at http://code.googie.com/ android/reference/android/app/Activity.html. You'll even find a spiffy graph. In essence, the handset uses a combination of the previous functions to alert you to the major events that can occur in your application: starting, closing, suspending, and resuming. Activities, as I've covered before, are going to be the core building block of any traditional application; they give you control over the screen and the ability to receive user inputs. You'll get more into user interaction in later chapters.

Thus Far

So far I've explored how activities are integrated within the phone, how they are started and stopped, and how they communicate on a basic level. I've demonstrated how to display a simple XML view screen and how to switch between two actives both in reaction to a key event and at the end of a set amount of time. In the short-term, you'll need to learn more about how Android uses intents, intent receivers, and intent filters to communicate. To do this, you'll need another sample application.

0 0

Post a comment