Alright, so at the end of the last
video, we added these private val tag
statements to our MainActivity class
and also our DownloadData class. And I
want to talk now about the warning that
Android Studio is giving us. And we can
see the warnings by just hovering our
mouse over the DownloadData class, and
you can see that there's two warnings
that have popped up. Now we're going to
ignore the first one - we know it's not
being used because we haven't written
the code to use it yet. But the second
warning is the one that's of interest
here, and that says that This AsyncTask
class should be static or leaks might
occur. And generally, it's not a good idea
to have inner classes inside an Activity,
and that's especially true when an inner
class is something like an AsyncTask,
that may be around and processing for a
long time. A static nested class is fine,
though. Now the difference is that an
inner class - which is what we have here -
holds a reference to the Activity. A
static nested class, on the other hand,
doesn't. In fact, it exists independently
of the class that it's nested in - the
nesting is just a packaging
convenience to keep all the code in the
same place.
Now we're going to come back to that in
more detail, because there's another app,
where it's natural to use a nested class,
and the explanation will then make more
sense. So if you don't understand all
this at the moment, don't worry - we're
just going to accept Android Studio's
suggestion, to make this class static. So
the lightbulb that'll appear when I
actually click on this DownloadData,
over here to the left - click on that now -
it offers here the options, down the
bottom, to move to companion object, which
is Kotlin's
equivalent of static. So I'm going to click
that option, and at that point in time,
you can see the code's been modified for
us and we've no longer got a warning - or
at least, not that particular warning
anyway. Now using an inner class doesn't
give a warning in Java, which is one
of the reasons why Kotlin code can often
be more robust. Alright, so we can add
some logging now to these two functions,
and see how the AsyncTask
behaves. Let's go ahead and do that. So we
added some logging in our onCreate
method, but let's do it now for the two
functions in DownloadData. So firstly,
for onPostExecute -
let's do that one first - and we're gonna add
the tagging, the logging for that,
after these super.onPostExecute. So
I'm going to type the Log.d
parentheses TAG. Then in double quotes
after a comma, I'm just going to type on
PostExecute colon, and I'll put parameter is
dollar - dollar sign - result. So that's that
one, and then also for the doin
Background, what I'm going to do is
delete the TODO line, and instead what I'm
going to do is add to that; Log.d
parentheses again, TAG comma space and
then we add double quotes, doin
Background. We're gonna put starts with,
then I'm going type dollar, left and
right curly braces, and within the curly
braces, p0 square bracket and zero - so
basically, zero in between square
brackets. Then we've got our right curly
brace as well. Then we'll also return
something here -
we're going to return doInBackground
completed. Alright, so currently our
doInBackground function doesn't do a
lot - it just returns a message saying
doInBackground has completed. And I've
also printed out the first parameter, so
you can see what happens when the doIn
Background function's called, and
obviously, that's this code here on
line 29. So overall, our AsyncTask isn't
doing very much at the moment, but by
looking at the logcat, we should be able
to get a good idea of when things are
being called. Now to run the task, we just
need to create an instance of the
DownloadData class, and then call its
execute function. We're going to do that
in onCreate, so after the TAG for the
logging rather, for the onCreate call
message - we're going to put it in there.
So I'm going to type val download
Data is equal to, and DownloadData with a
capital D for Download and a capital D
for Data, and then parentheses.
Then I'm going to type downloadData dot
execute, and in parentheses, URL goes here.
Then I'm gonna do another log, so Log.d
TAG comma space double quotes onCreate
done. Okay, so at this point now, we should
be able to run the app, and check log cat
to see what's happened. So let's go ahead
and do that, and we'll just look at
the emulator briefly, although it's not
gonna have anything other than the
Hello World widget show.
Alright, there's the Hello World with the
TextView widget and the title. So
we want to look at our logcat, though.
Let's do that - we'll open that up.
And we can actually see the call here,
when I've scrolled back up the top; on
Create: called, onCreate: done. doin
Background starts with URL goes here.
That URL goes here was the argument
that we passed, if you recall, on line 17.
And then we've got down here, onPostExecute:
parameter is doingBackground completed.
I've also got some other stuff here as
well, and that can look a bit horrible
with the logcat, with all sorts of other
log entries getting in the way. But we
can make it more readable, by filtering
on the two tags that we're interested in.
So to do that, in the logcat window, you
want to make sure firstly, that Regex is
actually checked, which it is here. And then
we just need to enter in the filter box,
over here to the left. If we enter
MainActivity and then the pipe character,
then download data, and that gives us a better
view of the actual data. Now, in case
you're wondering, the pipe character - or
vertical bar - that means or. So when I've
entered that in mainactivity, then the
pipe character downloaddata, that means,
basically, show output with mainactivity
or download data in the actual text, in
the actual log entries
themselves. So basically, we're looking to
see that the log entries can contain
either the word mainactivity or download
data. Now by the way, it's best to use
lower case only in that filter box,
because if you use any capitals, then you
actually have to match the tags exactly.
Okay, so the first thing to note is that
onCreate finishes before doin
Background starts. So we've got onCreate
called on the first line, then onCreate
done. Then after that, we can see that,
quite clearly, that doInBackground
starts with the URL goes here. So it
takes Android a little while to set up
all the threading for the AsyncTask, and
while it's doing that, our onCreate
finished because it didn't have anything
else to d. Now if we had more code in
onCreate, then doinBackground may well
have started before onCreate finished,
but the important thing here is that
onCreate didn't wait for the background
task to finish. And we can see, then, doin
Background starting, and the parameter it
received was
the string, as I mentioned - URL goes here -
that we passed when calling the execute
method. doInBackground then performs
its task on a separate thread, and it
doesn't take very long because it's not
really doing anything. But when it
finishes, it returns a string, which was
the type that we specified as the third
parameter, when we declared the Async
Task on line 22, here. Now the android
framework then takes over and calls the
onPostExecute method on the main
thread. The parameter passed to onPost
Execute is the return value from doin
Background. And again, we can see that in
the results here in the logcat;
parameter is doInBackground completed -
that's for onPostExecute. Now if we have a
look at onPostExecute, you can see that
that's where it's printing it out; and
doInBackground returned, doIn
Background completed - and that's where
it's getting the the value to display
in onPostExecute. So as you can see,
Android takes care of the complexity of
multi-threading. All we have to do to use
an AsyncTask, is to define the task that
should be done in the background, and
then decide what to do with any
values returned when the task completes.
Now in the next video, we'll get the
background task to actually download
some data, by adding code to the doIn
Background method. So I'll see you in
that next video.