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 add a separate Thread to our Service and drive home the point that Services are not Threads!
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 just got an ANR by trying to do
our downloading in our service.
0:00
But didn't we just say that services
are an application component
0:04
that can perform long running
operations in the background?
0:08
What gives?
0:11
Well, by default,
0:13
everything in an app runs on the main
thread, including our service.
0:15
So even if a service is performing long
running operations in the background
0:19
by default it will be doing those long
running operations on the main thread.
0:23
If we want our service to do
work on a separate thread,
0:28
we need to create that
separate thread ourselves.
0:31
Seems simple enough.
0:35
Now let's make our download service do
the downloading on a separate thread.
0:37
Let's close the Android manifest and
start with some planning.
0:42
On the left is the code from when we
created our own thread and main activity.
0:47
We created, named, and started
the thread in the on create method.
0:52
Then, in the on click method of our
button for each song we obtained and
0:58
set a message and
then sent that message using our handler.
1:03
Now we need to replicate
this in our service.
1:09
Just like an activity, a service also
has a life cycle and life cycle methods.
1:12
And one of these methods is the good or
onCreate method.
1:18
So we'll create, name and
start our thread, in the onCreate method.
1:23
And since we've now replaced this
message part with starting our service,
1:29
we should now be obtaining and
1:34
sending messages to our handler over
here in the onStartCommand method.
1:35
All right.
1:42
Let's start and download service and
remove the download song method.
1:43
We'll now be using our
download handler and
1:53
it still has its download
song method from before.
1:55
Let's also remove the call
to download the song.
2:00
Then let's override our
services on create method.
2:05
Let's place our cursor
above onStartCommand and
2:09
use control O to override
the onCreate method.
2:13
And let's delete this call to super.
2:19
We don't need it.
2:21
Now we need to create, name and start our
thread just like we did in our activity.
2:24
Let's start by creating a new download
thread at the top of the on create method.
2:32
Download thread thread
equals new download thread.
2:38
Then on the next line,
let's set the name of our thread.
2:46
Thread.setName DownloadThread.
2:50
And lastly let's start our thread,
thread.start.
2:56
Next up,
we need to send a message to our thread
3:04
each time on start command is called.
3:08
Under where we declare a song,
let's obtain a message, and
3:12
set it to a new message variable.
3:15
Message message equals message.obtain.
3:17
Then let's attach our song
variable to our message,
3:24
message.obj equals song,
3:27
and send the message using our handler,
which we currently don't have access to.
3:33
Let's quickly create a field for
our download handler.
3:39
private download handler
3:42
mhandler, then let's give it
a value at the bottom of on Create
3:48
mhandler equals thread but mhandler.
3:55
Lastly, back in on StartCommand,
4:01
let's send our message,
mHandler.sendMessage(message);,
4:04
great work!
4:13
Now that we're doing our download and
a separate thread,
4:15
again we shouldn't have any
issues with the app being slow or
4:18
not responding, but
let's test it out just to be sure.
4:23
Let's click the download button and
4:32
yikes the app crashed If
we look through the log.
4:36
And filter by errors.
4:46
It looks like we're getting a null pointer
exception because we're trying to invoke
4:50
the virtual method,
send message on a null object reference.
4:55
And if we click on the link
to jump to the error
5:05
it looks like that null
object is our handler.
5:10
Just like last time this
is because our main thread
5:15
is ahead of our download thread.
5:18
The main thread has already
finished the onCreate method and
5:21
moved on to the onStartCommand method all
5:25
before our download thread has
even created our download handler.
5:28
To fix this,
5:35
let's make our main thread wait until
the handler exists before we assign it.
5:36
Up in the on create method
above the assignment
5:43
to mHandler,let's type while thread.m
5:49
handler equals null and add our brackets.
5:54
We shouldn't have to worry
about a null handler any more.
6:00
Using an empty while loop like this
definitely isn't the best practice.
6:05
But it's the best we can do
with what we've learned so far.
6:10
Now let's test the app again and
hopefully everything will work.
6:14
Also make sure you have
the Android device monitor open so
6:20
we can see what happens when
we kill our app's process.
6:24
And if we click the download button,
it seems to be working.
6:28
And if we wait ten seconds,
We can see our downloads start coming in.
6:35
Nice.
6:45
Now let's switch to the Android device
monitor and kill our apps process
6:46
and if we check the log and
scroll up a little bit,
6:55
we can see a scheduling restart of
crashed service and there's our service.
7:01
It looks like it'll restart in 47 seconds.
7:10
So let's wait for 47 seconds and
see what happens.
7:17
And look at that, our process came back.
7:24
And check it out.
7:29
Our downloads are happening again.
7:31
What's going on here?
7:34
Let's find out in the next video.
7:37
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