Joe Asks

^ Shouldn't We Use a Background Service for Music?

We haven't said much about the Android Service class, but you may have seen it used in some music-playing examples on the Web. Basically, a Service is a way to start a background process that can run even after your current activity finishes. Services are similar to, but not quite the same as, Linux daemons. If you're writing a general-purpose music player and want the music to continue while you're reading mail or browsing the Web, then, yes, a Service would be appropriate. In most cases, though, you want the music to end when your program ends, so you don't need to use the Service class.

R.raw.main refers to res/raw/main.mp3. You can find these sound files in the Sudokuv3 project of the downloadable samples on the book's website.

The onPause() method is the paired bookend for onResume(). Android pauses the current activity prior to resuming a new one, so in Sudoku, when you start a new game, the Sudoku activity will be paused, and then the Game activity will be started. onPause() will also be called when the user presses the Back or Home key. These are all places where we want our title music to stop, so we call Music.stop() in onPause().

Now let's do something similar for the music on the Game activity:

Download Sudokuv3/src/org/example/sudoku/Game.java

@Override protected void onResume() { super.onResume(); Music.play(this, R.raw.game);

@Override protected void onPause() { super.onPause(); Music.stop(this);

f \ Sudoku Trivia

Dozens of Sudoku variants exist, although none has gained the popularity of the original. One uses a sixteen-by-sixteen grid, with hexadecimal numbers. Another, called Gattai 5 or Samurai Sudoku, uses five nine-by-nine grids that overlap at the corner regions.

If you compare this to what we did to the Sudoku class, you'll notice that we're referencing a different sound resource, R.raw.game (res/raw/ game.mp3).

The final piece of the musical puzzle is the Music class, which will manage the MediaPlayer class used to play the current music:

Download Sudokuv3/src/org/example/sudoku/Music.java

Line 1 package org.example.sudoku;

- import android.content.Context;

- import android.media.MediaPlayer;

- public class Music {

private static MediaPlayer mp = null;

10 public static void play(Context context, int resource) {

stop(context);

- mp = MediaPlayer.create(context, resource); mp.setLooping(true);

public static void stop(Context context) {

The play() method first calls the stop() method to halt whatever music is currently playing. Next, it creates a new MediaPlayer instance using MediaPlayer.create(), passing it a context and a resource ID.

After we have a player, we then set an option to make it repeat the music in a loop and then start it playing. The start() method comes back immediately.

The stop() method that begins on line 18 is simple. After a little defensive check to make sure we actually have a MediaPlayer to work with, we call its stop() and release() methods. The MediaPlayer.stop() method, strangely enough, stops the music. The release( ) method frees system resources associated with the player. Since those are native resources, we can't wait until normal Java garbage collection reclaims them. Leaving out release( ) is a good way to make your program fail unexpectedly (not that this has ever happened to me, of course; I'm just saying you should keep that in mind).

Now comes the fun part—try playing Sudoku with these changes in place. Stress test it in every way you can imagine, such as switching to different activities, pressing the Back button and the Home button from different points in the game, starting the program when it's already running at different points, rotating the display, and so forth. Proper life-cycle management is a pain sometimes, but your users will appreciate the effort.

0 0

Post a comment