1
00:00:04,730 --> 00:00:06,859
In the last video, we looked at how to

2
00:00:06,859 --> 00:00:10,160
use the Android AsyncTask class to run

3
00:00:10,160 --> 00:00:12,289
code in a background thread, so that we

4
00:00:12,289 --> 00:00:14,089
didn't cause our app to block while

5
00:00:14,089 --> 00:00:16,070
waiting for a long-running process, such

6
00:00:16,070 --> 00:00:17,779
as downloading data from the Internet.

7
00:00:17,779 --> 00:00:19,279
Now one thing that I didn't

8
00:00:19,279 --> 00:00:20,720
mention about that doInBackground

9
00:00:20,720 --> 00:00:24,020
method, was the var arg modifier in the

10
00:00:24,020 --> 00:00:26,899
parameter list. Now, variable length

11
00:00:26,899 --> 00:00:28,820
argument lists allow you to provide

12
00:00:28,820 --> 00:00:31,550
several values for the parameter. Now all

13
00:00:31,550 --> 00:00:33,170
the arguments you provide must be of the

14
00:00:33,170 --> 00:00:35,420
same type, so they must all be strings

15
00:00:35,420 --> 00:00:37,280
in this particular case, but we could

16
00:00:37,280 --> 00:00:39,110
pass in several URLs and have them

17
00:00:39,110 --> 00:00:41,270
downloaded one after the other, if we

18
00:00:41,270 --> 00:00:42,140
wanted to do so.

19
00:00:42,140 --> 00:00:43,550
Now we're not actually going to do

20
00:00:43,550 --> 00:00:45,260
that, but the option's there if you need

21
00:00:45,260 --> 00:00:47,030
it. So we're only going to use a single

22
00:00:47,030 --> 00:00:49,280
string value when we get the doin

23
00:00:49,280 --> 00:00:50,930
Background method to do our downloading,

24
00:00:50,930 --> 00:00:52,940
but you can pass multiple parameters

25
00:00:52,940 --> 00:00:55,400
to it if you want to. Now because it's

26
00:00:55,400 --> 00:00:59,030
specified as var arg - and this is here,

27
00:00:59,030 --> 00:01:00,290
you can see on line 30, is what I'm

28
00:01:00,290 --> 00:01:03,530
talking about. The p0 parameter is

29
00:01:03,530 --> 00:01:06,979
accessed as a string array inside the

30
00:01:06,979 --> 00:01:09,139
function. So the first item in the array

31
00:01:09,139 --> 00:01:11,840
is p0,with 0 in square brackets, and

32
00:01:11,840 --> 00:01:13,819
that's the value we included in the

33
00:01:13,819 --> 00:01:15,649
logcat, which is effectively the first

34
00:01:15,649 --> 00:01:18,170
parameter. Now if several URLs were

35
00:01:18,170 --> 00:01:20,569
provided when calling the execute method,

36
00:01:20,569 --> 00:01:23,270
we can access them as p0 square

37
00:01:23,270 --> 00:01:26,030
brackets 1, p0 square brackets 2 and so

38
00:01:26,030 --> 00:01:28,039
on. So what I mean by that is, we can we

39
00:01:28,039 --> 00:01:33,920
can access them to something like p0[1], p0[2],

40
00:01:33,920 --> 00:01:38,899
so on and so forth. Now p0 is an awful

41
00:01:38,899 --> 00:01:40,399
name for a parameter, so I'm going to

42
00:01:40,399 --> 00:01:42,709
rename that to URL which makes a lot

43
00:01:42,709 --> 00:01:46,069
more sense. Now Android Studio will

44
00:01:46,069 --> 00:01:48,049
rename all occurrences for us, when we

45
00:01:48,049 --> 00:01:50,079
right-click and choose Refactor Rename.

46
00:01:50,079 --> 00:01:52,849
So I'm gonna go ahead and do that; select

47
00:01:52,849 --> 00:01:55,369
Refactor then Rename, and I'm

48
00:01:55,369 --> 00:01:58,090
going to call that URL and press Enter.

49
00:01:58,090 --> 00:02:00,469
And you can see, conveniently it's also

50
00:02:00,469 --> 00:02:03,079
changed the reference to what was p0 on

51
00:02:03,079 --> 00:02:06,409
line 31. Now hopefully the code generator

52
00:02:06,409 --> 00:02:08,300
will use a better name in future. The

53
00:02:08,300 --> 00:02:09,889
more usual args would have been better

54
00:02:09,889 --> 00:02:13,069
than p0. Now we saw how to start the

55
00:02:13,069 --> 00:02:14,599
background task, which just involves

56
00:02:14,599 --> 00:02:17,030
creating an instance of our Download

57
00:02:17,030 --> 00:02:18,440
Data class and calling

58
00:02:18,440 --> 00:02:20,900
it's execute method, with any arguments

59
00:02:20,900 --> 00:02:23,210
that it needs. When the AsyncTask

60
00:02:23,210 --> 00:02:26,060
class's execute method's called, it takes

61
00:02:26,060 --> 00:02:27,380
care of setting up all the

62
00:02:27,380 --> 00:02:29,330
multi-threading, and then runs doin

63
00:02:29,330 --> 00:02:31,970
Background on a separate thread, passing

64
00:02:31,970 --> 00:02:33,650
it whatever arguments we gave to the

65
00:02:33,650 --> 00:02:35,900
execute method. Now when the task

66
00:02:35,900 --> 00:02:38,420
completes, the AsyncTask gets the

67
00:02:38,420 --> 00:02:40,250
return value from the other thread, and

68
00:02:40,250 --> 00:02:42,980
then calls the onPostExecute method

69
00:02:42,980 --> 00:02:45,800
with the return value. So with that said,

70
00:02:45,800 --> 00:02:47,390
now let's get our background thread to

71
00:02:47,390 --> 00:02:49,760
do something a little bit more useful. So

72
00:02:49,760 --> 00:02:51,050
we're going to make some changes to the

73
00:02:51,050 --> 00:02:52,460
code now, and I'm just going to close the

74
00:02:52,460 --> 00:02:54,230
logcat for now to make a bit more, I'll

75
00:02:54,230 --> 00:02:55,420
give it a bit more screen real estate.

76
00:02:55,420 --> 00:02:58,070
So we're going to leave the first log

77
00:02:58,070 --> 00:03:01,280
there - the log message. We're going to

78
00:03:01,280 --> 00:03:04,730
come up here and type in val space RSS

79
00:03:04,730 --> 00:03:09,790
Feed is equal to download XML

80
00:03:09,790 --> 00:03:13,220
parenthesis url square brackets with a

81
00:03:13,220 --> 00:03:16,850
zero in the middle. And then on the next

82
00:03:16,850 --> 00:03:19,570
line, I'm going to type if parentheses

83
00:03:19,570 --> 00:03:27,530
rssFeed dot is empty, then open a code

84
00:03:27,530 --> 00:03:34,040
block. We're gonna type Log.e tag, and in

85
00:03:34,040 --> 00:03:38,720
parentheses, doInBackground :

86
00:03:38,720 --> 00:03:41,989
space error downloading, to let us know

87
00:03:41,989 --> 00:03:43,520
there was a problem, and obviously, that's

88
00:03:43,520 --> 00:03:45,620
closing off the code block. Then

89
00:03:45,620 --> 00:03:46,880
on the last line, instead of returning

90
00:03:46,880 --> 00:03:48,860
doInBackground completed as a string,

91
00:03:48,860 --> 00:03:53,510
we're going to return the rssFeed. So when

92
00:03:53,510 --> 00:03:55,700
you use a vararg parameter, the actual

93
00:03:55,700 --> 00:03:57,680
values get passed into the method as an

94
00:03:57,680 --> 00:03:59,209
array - an array of strings, in this

95
00:03:59,209 --> 00:04:01,340
particular case. And because we're only

96
00:04:01,340 --> 00:04:02,959
going to call this method with a single

97
00:04:02,959 --> 00:04:04,610
parameter, we won't actually bother

98
00:04:04,610 --> 00:04:06,380
writing code to get more than one string.

99
00:04:06,380 --> 00:04:08,209
The one we're interested in will be the

100
00:04:08,209 --> 00:04:10,100
first one in the array, and that's this

101
00:04:10,100 --> 00:04:12,200
url[0] which you can see me referencing,

102
00:04:12,200 --> 00:04:15,019
which we've talked about previously. Now

103
00:04:15,019 --> 00:04:16,100
of course, we haven't written the

104
00:04:16,100 --> 00:04:18,709
download XML method yet, but that'll take

105
00:04:18,709 --> 00:04:21,649
care of downloading the feed, and it'll

106
00:04:21,649 --> 00:04:23,600
return a string containing the XML when

107
00:04:23,600 --> 00:04:25,610
it's finished. Now if anything goes wrong

108
00:04:25,610 --> 00:04:27,979
it's going to return an empty string, so

109
00:04:27,979 --> 00:04:29,390
that we can check to see if the return

110
00:04:29,390 --> 00:04:31,800
value is empty, and log an error if

111
00:04:31,800 --> 00:04:35,009
is. Now normally we'd use Log.d for

112
00:04:35,009 --> 00:04:37,470
writing a debug information to the log,

113
00:04:37,470 --> 00:04:40,199
but this will actually be an error. Now

114
00:04:40,199 --> 00:04:42,150
log.d entries shouldn't appear in the

115
00:04:42,150 --> 00:04:44,220
logcat when we release the production

116
00:04:44,220 --> 00:04:46,139
version of our apps. The build process

117
00:04:46,139 --> 00:04:48,690
removes them from the code. But in this

118
00:04:48,690 --> 00:04:50,129
particular case, we'd really want

119
00:04:50,129 --> 00:04:52,050
this message to remain, so I'm using

120
00:04:52,050 --> 00:04:55,229
log.e instead of Log.d to log

121
00:04:55,229 --> 00:04:57,270
this message as an error, rather than a

122
00:04:57,270 --> 00:04:59,729
debug level. And of course, I'm referring to

123
00:04:59,729 --> 00:05:03,659
the entry on line 34. Alright, so all

124
00:05:03,659 --> 00:05:05,969
the code we put in doInBackground will

125
00:05:05,969 --> 00:05:07,949
run asynchronously on a background

126
00:05:07,949 --> 00:05:10,199
thread, and that also includes any

127
00:05:10,199 --> 00:05:12,449
methods that it calls. So that means

128
00:05:12,449 --> 00:05:15,300
download XML will also be running on the

129
00:05:15,300 --> 00:05:16,139
background thread.

130
00:05:16,139 --> 00:05:18,479
Now when the download XML function

131
00:05:18,479 --> 00:05:21,060
returns, we'll either have the XML in the

132
00:05:21,060 --> 00:05:23,699
rssFeed string, in which case we'll just

133
00:05:23,699 --> 00:05:26,250
return it, or if we've got an empty string, in

134
00:05:26,250 --> 00:05:27,840
which case, we're going to log an error

135
00:05:27,840 --> 00:05:31,110
before returning. Now the download XML

136
00:05:31,110 --> 00:05:32,879
function will take a fairly typical

137
00:05:32,879 --> 00:05:35,159
approach. That's pretty well common when

138
00:05:35,159 --> 00:05:36,419
you're reading from a stream of data,

139
00:05:36,419 --> 00:05:39,330
such as data over the internet or data

140
00:05:39,330 --> 00:05:41,550
stored in a file on disk. So we're going

141
00:05:41,550 --> 00:05:44,190
to start by opening a http connection,

142
00:05:44,190 --> 00:05:46,590
which we use to access the stream of

143
00:05:46,590 --> 00:05:49,020
data coming over the internet from a URL.

144
00:05:49,020 --> 00:05:51,509
Now the connection provides an input

145
00:05:51,509 --> 00:05:53,490
stream, so we're going to be using an

146
00:05:53,490 --> 00:05:56,130
input stream reader to read the data

147
00:05:56,130 --> 00:05:58,289
from it. Now whenever you're dealing with

148
00:05:58,289 --> 00:05:59,940
a stream that's coming from a slow

149
00:05:59,940 --> 00:06:02,460
device, such as a disk drive or an

150
00:06:02,460 --> 00:06:04,529
internet connection, it's actually a good

151
00:06:04,529 --> 00:06:07,469
idea to use a buffered reader. Now a

152
00:06:07,469 --> 00:06:09,680
buffered reader, as the name suggests,

153
00:06:09,680 --> 00:06:11,819
buffers the data coming in from the

154
00:06:11,819 --> 00:06:13,889
stream. So instead of repeatedly

155
00:06:13,889 --> 00:06:16,110
accessing the hard drive or network, a

156
00:06:16,110 --> 00:06:18,479
block of data is read into a buffer in

157
00:06:18,479 --> 00:06:20,879
memory, and our program can read from the

158
00:06:20,879 --> 00:06:23,099
buffer. So that's the recommended way to

159
00:06:23,099 --> 00:06:25,710
read data from an input stream, so our

160
00:06:25,710 --> 00:06:28,050
app will use a buffered reader. I'm

161
00:06:28,050 --> 00:06:29,610
going to type the code for that inside

162
00:06:29,610 --> 00:06:31,919
the DownloadData class, and then we'll

163
00:06:31,919 --> 00:06:34,009
actually discuss the actual reading.

164
00:06:34,009 --> 00:06:36,539
Now I've already horrified any Java

165
00:06:36,539 --> 00:06:38,759
developers taking this course, so now I'm

166
00:06:38,759 --> 00:06:40,589
going to turn the tables, and I'm going

167
00:06:40,589 --> 00:06:42,570
to horrify any Kotlin developers in the

168
00:06:42,570 --> 00:06:44,669
course. Now don't worry, this next bit of

169
00:06:44,669 --> 00:06:45,220
code is only

170
00:06:45,220 --> 00:06:47,590
temporary, and we're gonna be rewriting it

171
00:06:47,590 --> 00:06:50,710
into more idiomatic Kotlin shortly. The

172
00:06:50,710 --> 00:06:52,630
entire block of code that I'm about to

173
00:06:52,630 --> 00:06:54,790
type in, in the rest of this video, can be

174
00:06:54,790 --> 00:06:56,650
written in just a few lines as we'll see,

175
00:06:56,650 --> 00:06:59,020
but it is much easier to understand if

176
00:06:59,020 --> 00:07:01,900
we use and see the long version first. So

177
00:07:01,900 --> 00:07:04,210
let's go ahead and do that. So I'm gonna

178
00:07:04,210 --> 00:07:08,370
start with the new function; private fun

179
00:07:08,370 --> 00:07:11,650
downloadXML, and as an argument, it's

180
00:07:11,650 --> 00:07:14,920
gonna be urlPath colon string

181
00:07:14,920 --> 00:07:19,600
question mark colon string, and then

182
00:07:19,600 --> 00:07:21,480
we'll use the left and right curly braces.

183
00:07:21,480 --> 00:07:23,590
And we're going to start by typing val

184
00:07:23,590 --> 00:07:31,060
xmlResult equals string builder. I'm

185
00:07:31,060 --> 00:07:34,750
gonna do a try, then within the try I'm gonna

186
00:07:34,750 --> 00:07:41,440
type val url equals URL urlPath val

187
00:07:41,440 --> 00:07:46,290
connection colon HttpURLConnection.

188
00:07:46,290 --> 00:07:48,480
Make sure you actually type here, the

189
00:07:48,480 --> 00:07:51,940
HttpURLConnection. In the past, students

190
00:07:51,940 --> 00:07:54,400
have actually typed Https, which is an

191
00:07:54,400 --> 00:07:55,750
entirely separate thing. So make sure you

192
00:07:55,750 --> 00:07:57,880
choose the correct one. So that's equal

193
00:07:57,880 --> 00:08:01,720
to url.openConnection

194
00:08:01,720 --> 00:08:06,280
parentheses, then space as HttpURL

195
00:08:06,280 --> 00:08:11,140
Connection, and again, not Https. Next, on

196
00:08:11,140 --> 00:08:13,690
the next line, val response is equal

197
00:08:13,690 --> 00:08:18,780
to connection.responseCode Log.d

198
00:08:18,780 --> 00:08:21,820
TAG and double quotes after the comma,

199
00:08:21,820 --> 00:08:28,690
downloadXML : The response code was, and

200
00:08:28,690 --> 00:08:32,289
dollar response. On the next line, we're

201
00:08:32,289 --> 00:08:33,940
going to type - actually we'll leave a space there 

202
00:08:33,940 --> 00:08:36,700
- on the line after that, val inputStream

203
00:08:36,700 --> 00:08:42,179
is equal to connection.inputStream.

204
00:08:42,179 --> 00:08:47,200
Then val inputStreamReader equals

205
00:08:47,200 --> 00:08:54,190
InputStreamReader inputStream, and val

206
00:08:54,190 --> 00:08:58,830
reader is equal to BufferedReader

207
00:08:58,830 --> 00:09:02,350
parentheses inputStreamReader - oops,

208
00:09:02,350 --> 00:09:05,080
parentheses there - then InputStream

209
00:09:05,080 --> 00:09:09,100
Reader. Alright, so starting off on line

210
00:09:09,100 --> 00:09:11,470
forty-six, I'm just using a String

211
00:09:11,470 --> 00:09:12,760
Builder, because we're going to be

212
00:09:12,760 --> 00:09:14,680
appending to the string a lot as we read

213
00:09:14,680 --> 00:09:17,650
characters from the inputStream. Now a

214
00:09:17,650 --> 00:09:19,390
StringBuilder is more efficient than

215
00:09:19,390 --> 00:09:21,670
just concatenating strings, and you'll

216
00:09:21,670 --> 00:09:23,560
see how that works in a minute. So the

217
00:09:23,560 --> 00:09:25,570
next thing you may find strange is the

218
00:09:25,570 --> 00:09:28,060
try block. When dealing with data from an

219
00:09:28,060 --> 00:09:30,040
external source, which basically means

220
00:09:30,040 --> 00:09:31,510
anything that isn't the computer's

221
00:09:31,510 --> 00:09:33,490
memory, there are actually a lot of

222
00:09:33,490 --> 00:09:35,980
things that can go wrong. The device may

223
00:09:35,980 --> 00:09:37,990
not be connected to the Internet, or the

224
00:09:37,990 --> 00:09:39,280
connection may drop while you're

225
00:09:39,280 --> 00:09:41,680
downloading data. It's possible that the

226
00:09:41,680 --> 00:09:43,300
Apple website might be down, which

227
00:09:43,300 --> 00:09:45,460
is rare, but you can't count on any

228
00:09:45,460 --> 00:09:47,470
websites being available 100% of the

229
00:09:47,470 --> 00:09:50,650
time. And it's also possible that the URL

230
00:09:50,650 --> 00:09:52,960
passed into the method isn't valid, which

231
00:09:52,960 --> 00:09:54,220
would prevent the connections from being

232
00:09:54,220 --> 00:09:57,040
made in the first place. So a try block

233
00:09:57,040 --> 00:09:59,290
is a way to wrap up a section of code,

234
00:09:59,290 --> 00:10:01,510
and catch any exceptions that occur

235
00:10:01,510 --> 00:10:04,180
while it's executing. Now the first

236
00:10:04,180 --> 00:10:05,800
exception that would be thrown in that

237
00:10:05,800 --> 00:10:08,560
code, is when we create a URL from the

238
00:10:08,560 --> 00:10:10,870
string that was passed in to download

239
00:10:10,870 --> 00:10:13,360
XML. There's no guarantee that our

240
00:10:13,360 --> 00:10:14,920
download XML method will be given a

241
00:10:14,920 --> 00:10:18,100
valid URL, in the URL path parameter, and

242
00:10:18,100 --> 00:10:20,740
if the method isn't valid, a malformed

243
00:10:20,740 --> 00:10:23,380
URL exception will be thrown. Now

244
00:10:23,380 --> 00:10:25,600
the way we deal with the exception is to

245
00:10:25,600 --> 00:10:29,110
catch it using a catch block. So what

246
00:10:29,110 --> 00:10:30,580
I'm going to do is, just move up here a

247
00:10:30,580 --> 00:10:33,910
little bit more, and after the right

248
00:10:33,910 --> 00:10:36,280
curly brace which closes off the try

249
00:10:36,280 --> 00:10:38,400
block, we're going to need to type catch

250
00:10:38,400 --> 00:10:42,490
parentheses e : and MalformedURL

251
00:10:42,490 --> 00:10:44,550
Exception, and select that from the list.

252
00:10:44,550 --> 00:10:47,140
You'll open a code block, and then type

253
00:10:47,140 --> 00:10:51,120
Log.e parentheses TAG comma space

254
00:10:51,120 --> 00:10:59,410
downloadXML. So invalid URL dollar left

255
00:10:59,410 --> 00:11:03,340
and right curly braces, e.message. Now

256
00:11:03,340 --> 00:11:05,680
I've used Log.e again there,

257
00:11:05,680 --> 00:11:07,600
rather than log.d, because this is an

258
00:11:07,600 --> 00:11:10,720
error and not just debug information. And

259
00:11:10,720 --> 00:11:11,720
you'll see that

260
00:11:11,720 --> 00:11:13,579
entry behind being logged to logcat,

261
00:11:13,579 --> 00:11:15,620
when we come to run the program because,

262
00:11:15,620 --> 00:11:17,480
at the moment, we're calling the Async,

263
00:11:17,480 --> 00:11:20,329
the AsyncTask's execute method with a

264
00:11:20,329 --> 00:11:23,240
very invalid URL - the string URL goes

265
00:11:23,240 --> 00:11:26,209
here. Now the next exception that we may

266
00:11:26,209 --> 00:11:28,310
get - that's an i/o exception.

267
00:11:28,310 --> 00:11:30,680
Now the first place we make an exception

268
00:11:30,680 --> 00:11:35,180
is on this line here, line 51, when we try

269
00:11:35,180 --> 00:11:37,399
to open the connection. In fact, an i/o

270
00:11:37,399 --> 00:11:38,870
exception can be thrown

271
00:11:38,870 --> 00:11:40,730
whenever code performs an input or

272
00:11:40,730 --> 00:11:42,860
output operation, such as reading or

273
00:11:42,860 --> 00:11:45,019
writing to a disk file or, like here,

274
00:11:45,019 --> 00:11:46,579
accessing the Internet.

275
00:11:46,579 --> 00:11:50,029
Now although we have a valid URL - URL if

276
00:11:50,029 --> 00:11:52,399
the code hasn't got that far - it may not

277
00:11:52,399 --> 00:11:54,410
be possible to open the connection if

278
00:11:54,410 --> 00:11:55,970
there's a problem with our internet

279
00:11:55,970 --> 00:11:58,100
connection. Now it's also possible that

280
00:11:58,100 --> 00:12:00,560
the URL may refer to a server that

281
00:12:00,560 --> 00:12:02,569
doesn't exist. Now, for example, if we

282
00:12:02,569 --> 00:12:05,899
spelt to Apple incorrectly as appl. So

283
00:12:05,899 --> 00:12:07,100
we're going to add another catch block

284
00:12:07,100 --> 00:12:09,350
here, under the first one, to catch IO

285
00:12:09,350 --> 00:12:11,000
exceptions. So go ahead and do that.

286
00:12:11,000 --> 00:12:15,519
So after the closing curly brace, catch

287
00:12:15,519 --> 00:12:21,410
parentheses e : IOException, and

288
00:12:21,410 --> 00:12:24,319
then closing parentheses and then open

289
00:12:24,319 --> 00:12:26,509
the code block. Log.E because it's

290
00:12:26,509 --> 00:12:28,850
an error again, TAG in parentheses comma

291
00:12:28,850 --> 00:12:31,579
space, then double quotes. Then it's gonna

292
00:12:31,579 --> 00:12:33,980
be downloadXML :

293
00:12:33,980 --> 00:12:41,389
IO Exception reading data :

294
00:12:41,389 --> 00:12:42,949
then dollar, then left and right curly

295
00:12:42,949 --> 00:12:46,759
braces, e.message again. So as you

296
00:12:46,759 --> 00:12:48,199
can see, you can have multiple catch

297
00:12:48,199 --> 00:12:50,000
blocks and when an exception's

298
00:12:50,000 --> 00:12:52,129
thrown, Kotlin will go through them in

299
00:12:52,129 --> 00:12:54,470
order, until it finds the first one that

300
00:12:54,470 --> 00:12:56,379
matches the exception that was thrown.

301
00:12:56,379 --> 00:12:59,180
Now the order that you catch the

302
00:12:59,180 --> 00:13:01,879
exceptions is important, because in our

303
00:13:01,879 --> 00:13:04,459
code here, a MalformedURLException is

304
00:13:04,459 --> 00:13:07,129
a subclass of IOException. Now we

305
00:13:07,129 --> 00:13:08,420
can check that if we hold down the

306
00:13:08,420 --> 00:13:10,939
command key, and click on the Malformed

307
00:13:10,939 --> 00:13:12,980
URLException, and on a PC running

308
00:13:12,980 --> 00:13:14,089
Windows or Linux that will be the

309
00:13:14,089 --> 00:13:16,610
Ctrl key. So we come down there - go to

310
00:13:16,610 --> 00:13:21,199
to Malformed Exception and click, and

311
00:13:21,199 --> 00:13:22,370
we can jump to the source for the

312
00:13:22,370 --> 00:13:24,439
exception class, as you can see here, and

313
00:13:24,439 --> 00:13:26,000
we can see that it extends

314
00:13:26,000 --> 00:13:28,100
IOException. So MalformedURL

315
00:13:28,100 --> 00:13:30,230
Exception on line ten, extends IO

316
00:13:30,230 --> 00:13:30,890
Exception.

317
00:13:30,890 --> 00:13:33,200
So if we'd caught these exceptions the

318
00:13:33,200 --> 00:13:35,360
other way round, we'd actually never see

319
00:13:35,360 --> 00:13:37,880
the message invalid URL - we'd just get IO

320
00:13:37,880 --> 00:13:39,950
exception reading data, which would make

321
00:13:39,950 --> 00:13:41,900
finding the cause of the problem a lot

322
00:13:41,900 --> 00:13:43,940
harder. Alright, so let's just close

323
00:13:43,940 --> 00:13:45,500
that file down again - that class file down

324
00:13:45,500 --> 00:13:47,600
again. Go back to where we were. Mow

325
00:13:47,600 --> 00:13:49,700
that's actually even more important, if

326
00:13:49,700 --> 00:13:51,740
you add another catch block to deal with

327
00:13:51,740 --> 00:13:54,200
all other exceptions. So I'm gonna come down

328
00:13:54,200 --> 00:13:56,600
here and do that. Add another catch on

329
00:13:56,600 --> 00:14:01,250
the next line, e : Exception, another

330
00:14:01,250 --> 00:14:02,690
code block again. It's gonna be Log.e

331
00:14:02,690 --> 00:14:06,290
parentheses TAG comma space double

332
00:14:06,290 --> 00:14:10,430
quote, Unknown error :

333
00:14:10,430 --> 00:14:12,500
dollar sign, left and curly braces,

334
00:14:12,500 --> 00:14:16,280
e.message. So if we put this last

335
00:14:16,280 --> 00:14:18,530
catch block first, then that would be the

336
00:14:18,530 --> 00:14:20,720
only one executed because all of our

337
00:14:20,720 --> 00:14:22,460
other exceptions are, ultimately, a

338
00:14:22,460 --> 00:14:25,880
subclass of exception. Alright, so let's

339
00:14:25,880 --> 00:14:28,190
end the video here now. In the next video,

340
00:14:28,190 --> 00:14:30,680
we'll start talking more about the Http

341
00:14:30,680 --> 00:14:32,660
connection, and how the server sends back

342
00:14:32,660 --> 00:14:35,090
a response code. So I'll see you in the next

343
00:14:35,090 --> 00:14:37,300
video.

