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 finally connect our Service and Activity by passing an IBinder
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
We've just finished setting up our
activity to communicate with our service.
0:00
And now that we've got them connected, or
0:04
bound, it's about time
they start communicating.
0:07
Earlier, I mentioned that we'll be
passing a reference to our service
0:11
to our activity.
0:15
And once we have that reference,
we can easily call the public play and
0:17
pause methods and player service.
0:21
So, how exactly do we get an instance
of our service into our activity?
0:24
Inside our anonymous
service connection class,
0:29
if we take a closer look at
the onServiceConnected method,
0:33
it looks like it gives us
an IBinder object named service.
0:36
Which is a strange name for an IBinder.
0:41
Let's change that to binder.
0:44
And if we flip over to
the PlayerService class,
0:47
we can find another IBinder object
as the return value from onBind.
0:50
When we return from onBind, the returned
IBinder object is what will be used in
0:56
the call to on service connected.
1:01
This IBinder object is what enables our
activity and our service to communicate.
1:04
Okay, let's break this down so
we can see how to solve it.
1:11
We're trying to get a reference to
our service into our activity, but
1:15
the only thing we're sending from our
service to our activity is an IBinder.
1:19
IBinder starts with a capital I,
which lets us now that it's an interface.
1:25
An interface is typically just
a collection of method signatures.
1:31
And when a class implements an interface,
1:35
that means that that class has added
bodies to all of those signatures.
1:38
So when it says IBinder, since we can't
create an instance of an interface, what
1:43
we are really supposed to use is a class
that implements the IBinder interface.
1:49
But if we look at the documentation for
1:54
the IBinder class, it says that instead
of implementing IBinder directly,
1:57
we should extend the Binder class,
which implements the IBinder interface.
2:02
So we need to create
a class that extends Binder
2:08
to send from our service to our activity.
2:12
This class is what lets us get a reference
to our service into our activity.
2:15
Let's start by creating
our new Binder class.
2:21
Since the whole point of our Binder
is to give access to our service,
2:25
we'll create this class inside
our PlayerService class.
2:29
Let's add it above our client methods and
call it LocalBinder.
2:33
Public class LocalBinder extends_Binder.
2:40
Cool.
2:50
Now let's add a method called get service
2:52
which will allow our activity
to access our service.
2:54
public_PlayerService, because we need
to return a PlayerService, getService.
2:57
And we'll return, PlayerService.this.
3:09
Now we need to return an instance of
this class and the onBind method.
3:17
Let's create a new IBinder
field named mBinder.
3:22
private IBinder mBinder.
3:28
And let's set it equal
to a new LocalBinder.
3:34
Remember, a local binder is an IBinder
3:40
because we extended the Binder class
which implements they IBinder interface.
3:43
Then, in onBind,
let's return mBinder instead of null.
3:49
Back in main activity,
right below where we declare inbound,
3:56
Let's create a new field for
our service called mPlayerService.
4:01
private PlayerService mPlayerService.
4:05
Then let's use our IBinder object and
4:11
onServiceConnected to
populate this new field.
4:13
At the bottom of onServiceConnected
let's create a new variable to hold
4:18
the LocalBinder from onService.
4:22
PlayerService.LocalBinder and
we'll call it LocalBinder and
4:26
let's set it equal to
the IBinder parameter passed in.
4:31
And use Alt+Enter to cast
the IBinder to a LocalBinder.
4:38
Finally, on the next line let's set
4:43
our new player service field,
mPlayerService,
4:47
= localBinder.getService.
4:52
All right, now that we finally have a way
to control our music from main activity,
4:58
we can get back to our OnClickListener.
5:04
Inside the OnClickListener
we should first add a check
5:07
to make sure we're bound to our service.
5:10
If we're not bound,
our service is probably null.
5:13
And if we try to call play on
a null object, that's an error.
5:17
So if mBound,
5:21
brackets.
5:26
Now we need to know whether we
should be playing or pausing.
5:30
We could just switch between play and
pause on each tab, but really
5:34
we'd like to decide which button to show
based on if the music is playing or not.
5:39
And whether or not the music is playing
is a responsibility of our PlayerService,
5:45
not our activity.
5:50
Let's add a new client method to
our PlayerService to let us know
5:52
music is playing.
5:56
Right below the Client Methods comment,
5:58
let's add a new is playing method
which will return a boolean.
6:01
public boolean isPlaying.
6:06
And inside,
let's return mPlayer.isPlaying.
6:12
Back in main activity,
after we've made sure that we're bound.
6:18
Let's check if music is playing.
6:22
if mPlayerService.isPlaying.
6:25
And if it is, let's pause the music and
change our play button to say play.
6:33
mPlayerService.pause and
6:38
mPlayButton.setText to Play.
6:44
If music is not playing, so else,
6:52
let's play the music and change
the text of our button to say pause.
6:57
mPlayerService.play and
7:01
mPlayButton.setText to pause.
7:06
Also, since we want our music to keep
playing even if we close the activity it's
7:13
possible that the activity could be
launched while music is already playing.
7:18
In that case a user would see a play
button, because that's the default.
7:23
But would also be hearing music.
7:28
So when we launch our activity, we should
check to see if music is already playing
7:30
and update this button accordingly.
7:35
At the bottom of the onServiceConnected
method, let's check to see if our song
7:38
is playing and if it is, let's change
the text of our button to say pause.
7:43
So if mPlayerService.isPlaying.
7:48
MPlayButton.setText, Pause.
7:54
Nice.
8:00
And if I click over to PlayerService, it
looks like I forgot my return statement.
8:03
Now it's finally time to run the app and
see if it works.
8:09
And if we hit the play button.
8:17
[MUSIC]
8:19
There's our music, and
the button now says pause.
8:21
And if we hit it again
it pauses the music.
8:26
Great job.
8:29
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