This course will be retired on June 1, 2025.
Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
In this video we’ll see why sometimes we need to both bind to and start a Service!
Related Links
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
Finally, we've hooked up our app to play
and pause music when we tap on a button.
0:00
Before we move on,
let's review how this all works.
0:05
We begin in the onStart method of main
activity with a call to bindService,
0:10
and we pass in a service
connection object.
0:15
Then onCreate will be called in
our service, followed by onBind.
0:18
Then the onServiceConnected
method of our service connection
0:25
gets notified when we
are successfully connected.
0:31
And we set mBound to true, and
retrieve our PlayerService variable
0:34
by casting the provided iBinder to a local
binder and calling getService on it.
0:40
Later on, when we tap the PlayButton for
the first time,
0:47
mBound should be true and
isPlaying should return false.
0:50
So we'll end up calling the play
method of our player service and
0:56
start hearing some music.
1:01
Pretty cool, right?
1:03
Definitely, and even though we've
correctly implemented binding,
1:04
our app still isn't quite right.
1:09
Let's launch the app again and
hit the PLAY button.
1:12
[MUSIC]
1:18
Then, let's go back to the home screen.
1:20
And what's that?
1:24
The music stopped.
1:26
That's no good,
1:27
we're supposed to be using a service
to let us play music in the background.
1:29
So why did it stop?
1:34
When we leave our app, the onStop method
of main activity is triggered, and
1:36
we unbind from our service.
1:41
And now that our service
doesn't have any clients left,
1:43
it's onUnbind method will be called,
followed by onDestroy.
1:46
We can even see these calls in the log.
1:51
And when onDestroy is called,
we release our media player, and
1:56
it stops playing our song.
2:00
Okay, but
which part of that was the problem?
2:04
Well, it depends on what
you're trying to do.
2:07
Since we're trying to
make a music player app,
2:11
we'd like the music to keep playing
even when our activity is long gone.
2:14
So the problem is that our
service is getting destroyed
2:19
when we leave our activity.
2:22
However, this is exactly what
we'd expect from a bound service.
2:25
When the last client unbinds,
it gets destroyed.
2:29
So what we really need is for
2:33
our player service to allow
both binding and the starting.
2:35
Let's take a closer look at why this is.
2:40
Right now our service is basically created
and destroyed right along with our
2:43
activity [SOUND], just like we would
expect from a bound service [SOUND].
2:48
But if music is playing
while we leave the activity,
2:53
we need our service not to be destroyed.
2:56
That way, if we open the activity again,
3:00
it'll bind to the same service and
we'll be able to control the music.
3:03
We can keep our service from being
destroyed by starting our service and
3:08
not stopping it until it's done playing.
3:12
This way, our service won't be destroyed
until it both doesn't have any clients,
3:15
and is done playing,
just what we're looking for.
3:21
In the OnClick listener of our PlayButton,
3:24
let's start our PlayerService
when we start playing our song.
3:28
Right above the call to
mPlayerService.play,
3:32
let's create an intent for
our PlayerService.
3:36
Intent intent = new
Intent(MainActivity.this,
3:40
PlayerService.class).
3:48
Remember, that if we just
use the this keyword,
3:53
we'd be referring to this
anonymous OnClickListener class.
3:56
Next, let's start our players
service by calling startService and
4:02
passing in the intent Nice,
4:06
over in our PlayerService class, let's
override the onStart command method so
4:15
our call to startService will
actually start our service.
4:21
Add a couple lines below onCreate, and
4:26
let's use Ctrl+O to override
onStartCommand, and
4:29
change the return value to
Service.START_NOT_STICKY.
4:34
We only want our service to be in
a started state while our song is playing.
4:44
If our app crashes,
the song won't be playing anymore.
4:50
And we shouldn't restart our service
because then we'd have a started service
4:54
with no music playing.
4:58
Our service can now be
successfully started, but
5:00
we still need to stop our
service when its job is done.
5:03
This service is used for
playback of a single song.
5:07
And when that song is done playing
we can safely stop our service.
5:11
At the top of onStartCommand, let's add an
OnCompletionListener to our media player,
5:16
mPlayer.setOnCompletionListener(new
MediaPlayer.OnCompletionListener.
5:23
And inside the onCompletionMethod,
let's call stopSelf with no parameters.
5:31
Remember, calling stopSelf with no
parameters stops the service immediately,
5:38
regardless of whether it's
still working or not.
5:44
Every time we tap the play button,
it will start our service,
5:47
and onStartCommand will be called.
5:51
But since we only care about one song and
one media player,
5:54
as soon as that song is finished playing,
we just want to stop our service,
5:58
regardless of how many
times it was started.
6:03
All right, now let's test the app
6:05
We can PLAY, and
PAUSE music just like before, but
6:14
if we hit PLAY again and then leave
the app, the music keeps playing.
6:19
Great job.
6:27
And if we look over to the log,
6:29
[MUSIC]
6:30
We can see the call to onUnbind,
but not the call to onDestroy,
6:34
which means our service
is no longer bound.
6:39
And since it wasn't destroyed,
it must be started.
6:43
And if we wait for the end of the song,
6:47
we can see our service finally get
destroyed just like we planned.
6:49
How cool is that?
6:54
You've just created a fully
functioning music player that'll even
6:56
keep playing in the background.
6:59
You should be super proud of what
you've accomplished, so go ahead and
7:01
take a minute to reflect on
just how awesome you are.
7:05
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up