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 refactor our Thread to use Handlers, Loopers, and Messages!
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
Now that we know how all of
these pieces fit together.
0:00
It's time for
us to get our hands dirty and
0:03
turn this boring self serve breed of
truck into something a lot more robust.
0:05
Let's start by making a new class for
our handler and
0:10
let's call it DownloadHandler And
0:14
let's make it extend
the android.os.Handler class.
0:22
Then, back in our DownloadThread,
0:29
let's declare a public
DownloadHandler field named M handler
0:32
mHandler.
0:45
Then, let's delete everything
in the run method and
0:47
type Looper.prepare,
0:51
this creates a looper for a thread and
also creates the message queue.
0:59
Next, let's initialize our
handler by typing mHandler
1:05
equals new DownloadHandler.
1:10
By default, a handler is associated
with the looper for the current thread.
1:16
Since we're in the run method of our
DownloadThread, the current thread
1:20
will be our DownloadThread,
instead of the main thread, perfect!
1:26
And once our handler is created,
the last step is to call
1:31
Looper.loop to start looping
over the message queue.
1:36
Back in main activity, let's take a look
at our download buttons on click method.
1:43
When we click this button,
we want to start downloading our playlist
1:50
one song at a time,
like ordering a bunch of burritos at once.
1:54
So inside this method, we'll be sending
messages, or runnables, to our handler for
2:00
processing.
2:04
Let's add a comment at the bottom
of this method, to say.
2:05
Send Messages or Runnables
2:12
to Handler for processing.
2:17
But before we implement this, there's
actually two problems we should fix.
2:22
The first problem is that we're
still creating a new thread
2:27
each time we click the button.
2:31
Since we're trying to use just one thread
with a message queue, this is no good.
2:33
The second, and much bigger issue,
is that if we write this code,
2:39
it will cause a null pointer exception.
2:43
Here we are in the main thread,
inside the onclick method.
2:47
We create a new thread,
give it a name, start it and
2:51
then we start sending messages or
runnables to the handler.
2:55
But look over here at our DownloadThread,
3:00
it's still working on getting set up and
hasn't initialized the handler yet.
3:02
When we call thread start,
our download threads run method and
3:08
will start executing almost immediately.
3:13
But as fast as that is, the main thread
moves on to the next line even faster.
3:17
So when we try to communicate with
our download threads handler,
3:24
it won't have been created yet and our app
will crash with a null pointer exception.
3:28
We'll need to start our thread
before we get to the OnClick method.
3:33
Let's cut out our thread code and
paste it above in the on create method.
3:38
Awesome!
Back in the on click method let's do some
3:49
more planning.
3:52
We could create a new runnable for
each song we want to download.
3:55
But then we need to specify not
only which song to download, but
3:59
also how to download it like bringing
your own recipe to the burrito truck.
4:03
Wouldn't it be better if we could just
give our handler a bunch of song titles
4:09
and we could trust it to
handle them all by itself?
4:13
Yes, yes it would.
4:17
Let's start by changing our comment
to no longer include runnables.
4:19
Then, let's add a for
each loop to loop through the playlist.
4:25
For (String song : and Playlist.songs and
4:32
brackets, inside the loop,
4:37
let's create a new message
variable named message.
4:40
And let set it equal to Message.obtain.
4:52
We could create a new message object, but
4:58
since messages are used all
over the operating system,
5:01
Android keeps a pool of message
objects available for us to use.
5:05
This way,
Android doesn't need to keep creating and
5:10
deleting a bunch of message objects.
5:13
Once a message has been handled, it just
goes back to the pool to be re-used.
5:16
Now that we've got our message,
on the next line,
5:22
let's type message.obj = song;.
5:27
The OBJ property of a message lets us add
any type of object we want to our message.
5:31
Since we want to tell our handler
about a song to download,
5:39
we'll attach the song name to our message.
5:43
Lastly, we just need to send
our message to our handler, so
5:47
it can be added to the message queue.
5:51
We can do this by typing
thread.mHandler.sendMessage and
5:54
passing in our message.
6:03
And remember, that we should declare
thread as final, so we can use it and
6:06
our onclick method.
6:10
This might have happened automatically,
almost done.
6:12
The last thing we need to do,
6:16
is tell our handler what it should do,
when it gets a message.
6:18
We can do this but over riding our
handlers, handle message method.
6:23
Let's go to the download handler class,
and
6:29
hit Ctrl+O to bring up
the over ride dialog.
6:32
Then let's choose to override
the handleMessage method.
6:35
And once we've done that,
all we need to do is call our download
6:40
song method with the song
name supplied by our message.
6:45
Let's cut the download song method
out of our DownloadThread and
6:51
paste it into our DownloadHandler.
6:59
Then let's quickly update
the tag constant Alt+Enter,
7:06
downloadhandler.class.get simple name and
7:11
instead of calling super.handlemessage.
7:15
Let's call downloadSong, and
7:19
pass in the song attached to our message,
7:23
msg.obj.toString, to
turn it into a string.
7:29
Lastly, let's update the download song
method to take in a song, String song.
7:37
And let's change the log message
to include the song name.
7:45
Great work!
7:55
I know this stuff seems complicated,
but you're doing a fantastic job.
7:56
And the next video, will test our app and
learn about some potential improvements
8:01
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