1
00:00:05,490 --> 00:00:06,760
Alright, so at the end of the last

2
00:00:06,760 --> 00:00:09,270
video, we added these private val tag

3
00:00:09,270 --> 00:00:12,130
statements to our MainActivity class

4
00:00:12,130 --> 00:00:15,090
and also our DownloadData class. And I

5
00:00:15,090 --> 00:00:17,720
want to talk now about the warning that

6
00:00:17,720 --> 00:00:20,000
Android Studio is giving us. And we can

7
00:00:20,000 --> 00:00:22,160
see the warnings by just hovering our

8
00:00:22,160 --> 00:00:24,310
mouse over the DownloadData class, and

9
00:00:24,310 --> 00:00:26,600
you can see that there's two warnings

10
00:00:26,600 --> 00:00:28,470
that have popped up. Now we're going to

11
00:00:28,470 --> 00:00:30,560
ignore the first one - we know it's not

12
00:00:30,560 --> 00:00:32,040
being used because we haven't written

13
00:00:32,040 --> 00:00:34,380
the code to use it yet. But the second

14
00:00:34,380 --> 00:00:35,570
warning is the one that's of interest

15
00:00:35,570 --> 00:00:38,350
here, and that says that This AsyncTask

16
00:00:38,350 --> 00:00:40,800
class should be static or leaks might

17
00:00:40,800 --> 00:00:43,590
occur. And generally, it's not a good idea

18
00:00:43,590 --> 00:00:45,700
to have inner classes inside an Activity,

19
00:00:45,700 --> 00:00:48,610
and that's especially true when an inner

20
00:00:48,610 --> 00:00:51,150
class is something like an AsyncTask,

21
00:00:51,150 --> 00:00:53,000
that may be around and processing for a

22
00:00:53,000 --> 00:00:56,210
long time. A static nested class is fine,

23
00:00:56,210 --> 00:00:58,620
though. Now the difference is that an

24
00:00:58,620 --> 00:01:00,920
inner class - which is what we have here -

25
00:01:00,920 --> 00:01:03,120
holds a reference to the Activity. A

26
00:01:03,120 --> 00:01:05,019
static nested class, on the other hand,

27
00:01:05,019 --> 00:01:07,800
doesn't. In fact, it exists independently

28
00:01:07,800 --> 00:01:09,920
of the class that it's nested in - the

29
00:01:09,920 --> 00:01:11,180
nesting is just a packaging

30
00:01:11,180 --> 00:01:13,009
convenience to keep all the code in the

31
00:01:13,009 --> 00:01:14,009
same place.

32
00:01:14,009 --> 00:01:15,619
Now we're going to come back to that in

33
00:01:15,619 --> 00:01:18,109
more detail, because there's another app,

34
00:01:18,109 --> 00:01:20,340
where it's natural to use a nested class,

35
00:01:20,340 --> 00:01:21,899
and the explanation will then make more

36
00:01:21,899 --> 00:01:24,049
sense. So if you don't understand all

37
00:01:24,049 --> 00:01:25,960
this at the moment, don't worry - we're

38
00:01:25,960 --> 00:01:27,630
just going to accept Android Studio's

39
00:01:27,630 --> 00:01:31,070
suggestion, to make this class static. So

40
00:01:31,070 --> 00:01:32,369
the lightbulb that'll appear when I

41
00:01:32,369 --> 00:01:33,890
actually click on this DownloadData,

42
00:01:33,890 --> 00:01:37,140
over here to the left - click on that now -

43
00:01:37,140 --> 00:01:39,490
it offers here the options, down the

44
00:01:39,490 --> 00:01:42,600
bottom, to move to companion object, which

45
00:01:42,600 --> 00:01:43,600
is Kotlin's

46
00:01:43,600 --> 00:01:45,619
equivalent of static. So I'm going to click

47
00:01:45,619 --> 00:01:48,850
that option, and at that point in time,

48
00:01:48,850 --> 00:01:50,469
you can see the code's been modified for

49
00:01:50,469 --> 00:01:52,960
us and we've no longer got a warning - or

50
00:01:52,960 --> 00:01:54,100
at least, not that particular warning

51
00:01:54,100 --> 00:01:57,159
anyway. Now using an inner class doesn't

52
00:01:57,159 --> 00:01:59,350
give a warning in Java, which is one

53
00:01:59,350 --> 00:02:01,310
of the reasons why Kotlin code can often

54
00:02:01,310 --> 00:02:04,490
be more robust. Alright, so we can add

55
00:02:04,490 --> 00:02:06,509
some logging now to these two functions,

56
00:02:06,509 --> 00:02:08,310
and see how the AsyncTask

57
00:02:08,310 --> 00:02:11,150
behaves. Let's go ahead and do that. So we

58
00:02:11,150 --> 00:02:13,050
added some logging in our onCreate

59
00:02:13,050 --> 00:02:14,920
method, but let's do it now for the two

60
00:02:14,920 --> 00:02:17,640
functions in DownloadData. So firstly,

61
00:02:17,640 --> 00:02:18,640
for onPostExecute -

62
00:02:18,640 --> 00:02:20,260
let's do that one first - and we're gonna add

63
00:02:20,260 --> 00:02:23,060
the tagging, the logging for that,

64
00:02:23,060 --> 00:02:25,810
after these super.onPostExecute. So

65
00:02:25,810 --> 00:02:27,830
I'm going to type the Log.d

66
00:02:27,830 --> 00:02:31,540
parentheses TAG. Then in double quotes

67
00:02:31,540 --> 00:02:33,390
after a comma, I'm just going to type on

68
00:02:33,390 --> 00:02:40,930
PostExecute colon, and I'll put parameter is

69
00:02:40,930 --> 00:02:44,830
dollar - dollar sign - result. So that's that

70
00:02:44,830 --> 00:02:45,920
one, and then also for the doin

71
00:02:45,920 --> 00:02:47,920
Background, what I'm going to do is

72
00:02:47,920 --> 00:02:51,500
delete the TODO line, and instead what I'm

73
00:02:51,500 --> 00:02:56,010
going to do is add to that; Log.d

74
00:02:56,010 --> 00:02:58,390
parentheses again, TAG comma space and

75
00:02:58,390 --> 00:03:00,750
then we add double quotes, doin

76
00:03:00,750 --> 00:03:05,280
Background. We're gonna put starts with,

77
00:03:05,280 --> 00:03:08,630
then I'm going type dollar, left and

78
00:03:08,630 --> 00:03:10,620
right curly braces, and within the curly

79
00:03:10,620 --> 00:03:15,150
braces, p0 square bracket and zero - so

80
00:03:15,150 --> 00:03:16,900
basically, zero in between square

81
00:03:16,900 --> 00:03:19,410
brackets. Then we've got our right curly

82
00:03:19,410 --> 00:03:21,340
brace as well. Then we'll also return

83
00:03:21,340 --> 00:03:22,730
something here -

84
00:03:22,730 --> 00:03:29,080
we're going to return doInBackground

85
00:03:29,080 --> 00:03:32,480
completed. Alright, so currently our

86
00:03:32,480 --> 00:03:34,410
doInBackground function doesn't do a

87
00:03:34,410 --> 00:03:36,200
lot - it just returns a message saying

88
00:03:36,200 --> 00:03:38,681
doInBackground has completed. And I've

89
00:03:38,681 --> 00:03:41,010
also printed out the first parameter, so

90
00:03:41,010 --> 00:03:42,620
you can see what happens when the doIn

91
00:03:42,620 --> 00:03:44,680
Background function's called, and

92
00:03:44,680 --> 00:03:47,450
obviously, that's this code here on

93
00:03:47,450 --> 00:03:52,570
line 29. So overall, our AsyncTask isn't

94
00:03:52,570 --> 00:03:54,460
doing very much at the moment, but by

95
00:03:54,460 --> 00:03:56,581
looking at the logcat, we should be able

96
00:03:56,581 --> 00:03:58,100
to get a good idea of when things are

97
00:03:58,100 --> 00:04:01,010
being called. Now to run the task, we just

98
00:04:01,010 --> 00:04:03,150
need to create an instance of the

99
00:04:03,150 --> 00:04:06,240
DownloadData class, and then call its

100
00:04:06,240 --> 00:04:08,260
execute function. We're going to do that

101
00:04:08,260 --> 00:04:12,240
in onCreate, so after the TAG for the

102
00:04:12,240 --> 00:04:14,040
logging rather, for the onCreate call

103
00:04:14,040 --> 00:04:15,740
message - we're going to put it in there.

104
00:04:15,740 --> 00:04:18,358
So I'm going to type val download

105
00:04:18,358 --> 00:04:23,590
Data is equal to, and DownloadData with a

106
00:04:23,590 --> 00:04:26,770
capital D for Download and a capital D

107
00:04:26,770 --> 00:04:29,749
for Data, and then parentheses.

108
00:04:29,749 --> 00:04:33,849
Then I'm going to type downloadData dot

109
00:04:33,849 --> 00:04:38,569
execute, and in parentheses, URL goes here.

110
00:04:38,569 --> 00:04:44,400
Then I'm gonna do another log, so Log.d

111
00:04:44,400 --> 00:04:47,900
TAG comma space double quotes onCreate

112
00:04:47,900 --> 00:04:55,889
done. Okay, so at this point now, we should

113
00:04:55,889 --> 00:04:58,210
be able to run the app, and check log cat

114
00:04:58,210 --> 00:05:00,210
to see what's happened. So let's go ahead

115
00:05:00,210 --> 00:05:05,340
and do that, and we'll just look at

116
00:05:05,340 --> 00:05:06,969
the emulator briefly, although it's not

117
00:05:06,969 --> 00:05:08,360
gonna have anything other than the

118
00:05:08,360 --> 00:05:12,270
Hello World widget show.

119
00:05:12,270 --> 00:05:13,430
Alright, there's the Hello World with the

120
00:05:13,430 --> 00:05:15,189
TextView widget and the title. So

121
00:05:15,189 --> 00:05:17,529
we want to look at our logcat, though.

122
00:05:17,529 --> 00:05:21,650
Let's do that - we'll open that up.

123
00:05:21,650 --> 00:05:24,629
And we can actually see the call here,

124
00:05:24,629 --> 00:05:25,860
when I've scrolled back up the top; on

125
00:05:25,860 --> 00:05:29,050
Create: called, onCreate: done. doin

126
00:05:29,050 --> 00:05:31,689
Background starts with URL goes here.

127
00:05:31,689 --> 00:05:33,310
That URL goes here was the argument

128
00:05:33,310 --> 00:05:35,960
that we passed, if you recall, on line 17.

129
00:05:35,960 --> 00:05:38,449
And then we've got down here, onPostExecute:

130
00:05:38,449 --> 00:05:40,560
parameter is doingBackground completed.

131
00:05:40,560 --> 00:05:43,139
I've also got some other stuff here as

132
00:05:43,139 --> 00:05:45,900
well, and that can look a bit horrible

133
00:05:45,900 --> 00:05:47,229
with the logcat, with all sorts of other

134
00:05:47,229 --> 00:05:49,431
log entries getting in the way. But we

135
00:05:49,431 --> 00:05:51,740
can make it more readable, by filtering

136
00:05:51,740 --> 00:05:54,319
on the two tags that we're interested in.

137
00:05:54,319 --> 00:05:56,749
So to do that, in the logcat window, you

138
00:05:56,749 --> 00:05:58,830
want to make sure firstly, that Regex is

139
00:05:58,830 --> 00:06:01,889
actually checked, which it is here. And then

140
00:06:01,889 --> 00:06:03,759
we just need to enter in the filter box,

141
00:06:03,759 --> 00:06:06,069
over here to the left. If we enter

142
00:06:06,069 --> 00:06:11,759
MainActivity and then the pipe character,

143
00:06:11,759 --> 00:06:18,460
then download data, and that gives us a better

144
00:06:18,460 --> 00:06:21,280
view of the actual data. Now, in case

145
00:06:21,280 --> 00:06:23,909
you're wondering, the pipe character - or

146
00:06:23,909 --> 00:06:26,599
vertical bar - that means or. So when I've

147
00:06:26,599 --> 00:06:29,009
entered that in mainactivity, then the

148
00:06:29,009 --> 00:06:32,009
pipe character downloaddata, that means,

149
00:06:32,009 --> 00:06:34,189
basically, show output with mainactivity

150
00:06:34,189 --> 00:06:37,300
or download data in the actual text, in

151
00:06:37,300 --> 00:06:38,629
the actual log entries

152
00:06:38,629 --> 00:06:40,449
themselves. So basically, we're looking to

153
00:06:40,449 --> 00:06:41,909
see that the log entries can contain

154
00:06:41,909 --> 00:06:44,270
either the word mainactivity or download

155
00:06:44,270 --> 00:06:46,970
data. Now by the way, it's best to use

156
00:06:46,970 --> 00:06:49,939
lower case only in that filter box,

157
00:06:49,939 --> 00:06:51,779
because if you use any capitals, then you

158
00:06:51,779 --> 00:06:54,770
actually have to match the tags exactly.

159
00:06:54,770 --> 00:06:56,539
Okay, so the first thing to note is that

160
00:06:56,539 --> 00:06:58,830
onCreate finishes before doin

161
00:06:58,830 --> 00:07:00,509
Background starts. So we've got onCreate

162
00:07:00,509 --> 00:07:02,960
called on the first line, then onCreate

163
00:07:02,960 --> 00:07:06,229
done. Then after that, we can see that,

164
00:07:06,229 --> 00:07:08,860
quite clearly, that doInBackground

165
00:07:08,860 --> 00:07:11,620
starts with the URL goes here. So it

166
00:07:11,620 --> 00:07:13,169
takes Android a little while to set up

167
00:07:13,169 --> 00:07:15,669
all the threading for the AsyncTask, and

168
00:07:15,669 --> 00:07:17,610
while it's doing that, our onCreate

169
00:07:17,610 --> 00:07:19,240
finished because it didn't have anything

170
00:07:19,240 --> 00:07:21,810
else to d. Now if we had more code in

171
00:07:21,810 --> 00:07:24,050
onCreate, then doinBackground may well

172
00:07:24,050 --> 00:07:26,360
have started before onCreate finished,

173
00:07:26,360 --> 00:07:28,169
but the important thing here is that

174
00:07:28,169 --> 00:07:30,389
onCreate didn't wait for the background

175
00:07:30,389 --> 00:07:33,639
task to finish. And we can see, then, doin

176
00:07:33,639 --> 00:07:35,949
Background starting, and the parameter it

177
00:07:35,949 --> 00:07:36,949
received was

178
00:07:36,949 --> 00:07:39,069
the string, as I mentioned - URL goes here -

179
00:07:39,069 --> 00:07:41,249
that we passed when calling the execute

180
00:07:41,249 --> 00:07:43,870
method. doInBackground then performs

181
00:07:43,870 --> 00:07:46,550
its task on a separate thread, and it

182
00:07:46,550 --> 00:07:48,089
doesn't take very long because it's not

183
00:07:48,089 --> 00:07:49,370
really doing anything. But when it

184
00:07:49,370 --> 00:07:52,129
finishes, it returns a string, which was

185
00:07:52,129 --> 00:07:54,030
the type that we specified as the third

186
00:07:54,030 --> 00:07:56,440
parameter, when we declared the Async

187
00:07:56,440 --> 00:08:02,999
Task on line 22, here. Now the android

188
00:08:02,999 --> 00:08:04,680
framework then takes over and calls the

189
00:08:04,680 --> 00:08:07,020
onPostExecute method on the main

190
00:08:07,020 --> 00:08:10,180
thread. The parameter passed to onPost

191
00:08:10,180 --> 00:08:12,659
Execute is the return value from doin

192
00:08:12,659 --> 00:08:15,900
Background. And again, we can see that in

193
00:08:15,900 --> 00:08:17,249
the results here in the logcat;

194
00:08:17,249 --> 00:08:19,529
parameter is doInBackground completed -

195
00:08:19,529 --> 00:08:21,909
that's for onPostExecute. Now if we have a

196
00:08:21,909 --> 00:08:25,169
look at onPostExecute, you can see that

197
00:08:25,169 --> 00:08:26,600
that's where it's printing it out; and

198
00:08:26,600 --> 00:08:28,229
doInBackground returned, doIn

199
00:08:28,229 --> 00:08:29,500
Background completed - and that's where

200
00:08:29,500 --> 00:08:31,520
it's getting the the value to display

201
00:08:31,520 --> 00:08:34,979
in onPostExecute. So as you can see,

202
00:08:34,979 --> 00:08:37,690
Android takes care of the complexity of

203
00:08:37,690 --> 00:08:40,469
multi-threading. All we have to do to use

204
00:08:40,469 --> 00:08:43,010
an AsyncTask, is to define the task that

205
00:08:43,010 --> 00:08:45,260
should be done in the background, and

206
00:08:45,260 --> 00:08:46,779
then decide what to do with any

207
00:08:46,779 --> 00:08:50,350
values returned when the task completes.

208
00:08:50,350 --> 00:08:51,509
Now in the next video, we'll get the

209
00:08:51,509 --> 00:08:53,170
background task to actually download

210
00:08:53,170 --> 00:08:55,470
some data, by adding code to the doIn

211
00:08:55,470 --> 00:08:57,420
Background method. So I'll see you in

212
00:08:57,420 --> 00:08:58,190
that next video.

