This course will be retired on July 14, 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
Well done!
You have completed Threads and Services!
You have completed Threads and Services!
Preview
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