1
00:00:04,740 --> 00:00:06,750
now that we've seen how to use a view

2
00:00:06,750 --> 00:00:09,000
model and live data in a very simple app

3
00:00:09,000 --> 00:00:10,860
it's time to look at something a bit

4
00:00:10,860 --> 00:00:13,260
more complex when we finished the top to

5
00:00:13,260 --> 00:00:15,510
him downloader app it still had one

6
00:00:15,510 --> 00:00:18,449
floor we tried to avoid unnecessary yard

7
00:00:18,449 --> 00:00:21,300
downloads as much as possible but the

8
00:00:21,300 --> 00:00:23,039
app still downloaded the data again

9
00:00:23,039 --> 00:00:25,170
after a configuration change such as

10
00:00:25,170 --> 00:00:28,020
rotating the device at the time I

11
00:00:28,020 --> 00:00:30,000
suggested that you could use a loader to

12
00:00:30,000 --> 00:00:31,710
prevent this and said that would be

13
00:00:31,710 --> 00:00:33,270
covering loaders later in the course

14
00:00:33,270 --> 00:00:37,500
however in June 2018 Google deprecated

15
00:00:37,500 --> 00:00:39,420
the loader classes so we're now going to

16
00:00:39,420 --> 00:00:42,000
be using the view model plus instead

17
00:00:42,000 --> 00:00:44,460
we've seen that a view model survives a

18
00:00:44,460 --> 00:00:46,590
configuration change which means it

19
00:00:46,590 --> 00:00:48,180
shouldn't have to download the data

20
00:00:48,180 --> 00:00:51,210
again when the device is rotated so in

21
00:00:51,210 --> 00:00:52,710
this video we'll start the process of

22
00:00:52,710 --> 00:00:55,079
changing the top 10 downloader to use a

23
00:00:55,079 --> 00:00:58,230
view model and solve this problem so

24
00:00:58,230 --> 00:01:00,210
start with the top 10 downloaded project

25
00:01:00,210 --> 00:01:01,860
open and you can see that I've got that

26
00:01:01,860 --> 00:01:04,379
open on screen you can download that so

27
00:01:04,379 --> 00:01:07,140
from the final video in section 7 where

28
00:01:07,140 --> 00:01:09,390
we created the top 10 download our app

29
00:01:09,390 --> 00:01:11,760
in this course if you need to so first

30
00:01:11,760 --> 00:01:13,890
thing I'm looking at main activity you

31
00:01:13,890 --> 00:01:15,270
can see it's got quite a bit of code

32
00:01:15,270 --> 00:01:17,490
that's concerned with the UI as we

33
00:01:17,490 --> 00:01:19,470
scroll down and check out so it needs to

34
00:01:19,470 --> 00:01:21,240
keep track of the feed limit that the

35
00:01:21,240 --> 00:01:23,880
user selected in order to make the menu

36
00:01:23,880 --> 00:01:26,670
correctly reflect their choice now

37
00:01:26,670 --> 00:01:28,560
because the feed limit is used to

38
00:01:28,560 --> 00:01:31,080
construct the URL it makes sense to

39
00:01:31,080 --> 00:01:33,840
leave responsibility for restoring feed

40
00:01:33,840 --> 00:01:36,420
URL with main activity as well you may

41
00:01:36,420 --> 00:01:38,100
decide to do things differently but I

42
00:01:38,100 --> 00:01:40,229
like the fact that the view model isn't

43
00:01:40,229 --> 00:01:41,960
going to know how to construct the gyro

44
00:01:41,960 --> 00:01:44,520
it'll be given a fully form link to the

45
00:01:44,520 --> 00:01:46,830
RSS feed and doesn't have to worry about

46
00:01:46,830 --> 00:01:48,540
formatting it with different feed limits

47
00:01:48,540 --> 00:01:51,180
so this separation of responsibilities

48
00:01:51,180 --> 00:01:53,729
makes it easier to make changes to your

49
00:01:53,729 --> 00:01:56,189
app without breaking things you could

50
00:01:56,189 --> 00:01:58,320
use a different feed for example and the

51
00:01:58,320 --> 00:02:00,299
view model would still work well so

52
00:02:00,299 --> 00:02:01,560
moving down a bit further

53
00:02:01,560 --> 00:02:03,810
most of the conveyor code in here is

54
00:02:03,810 --> 00:02:05,490
concerned as I mentioned with the gyro

55
00:02:05,490 --> 00:02:07,979
but looking down here we've got this

56
00:02:07,979 --> 00:02:10,439
function that download gyro well that

57
00:02:10,439 --> 00:02:11,670
shouldn't be in here because that's not

58
00:02:11,670 --> 00:02:14,189
a UI function and also scorned a little

59
00:02:14,189 --> 00:02:15,629
bit further we've looked towards the

60
00:02:15,629 --> 00:02:17,230
bottom of the class

61
00:02:17,230 --> 00:02:19,780
we've got this companion object and

62
00:02:19,780 --> 00:02:21,489
that's the downloaded companion object

63
00:02:21,489 --> 00:02:22,930
we shouldn't have that in this class

64
00:02:22,930 --> 00:02:25,390
either well that's a good place to start

65
00:02:25,390 --> 00:02:27,099
I think this download our companion

66
00:02:27,099 --> 00:02:28,930
object so what I'm going to do is create

67
00:02:28,930 --> 00:02:31,150
a new Copland file class let's go ahead

68
00:02:31,150 --> 00:02:33,970
and do that it's a new Kotlin file class

69
00:02:33,970 --> 00:02:37,270
we'll call this one download data now

70
00:02:37,270 --> 00:02:38,620
because we're going to be cutting all

71
00:02:38,620 --> 00:02:39,790
the code we've got all the code we need

72
00:02:39,790 --> 00:02:41,980
I won't bother selecting class from the

73
00:02:41,980 --> 00:02:44,950
drop-down so next we want to go back to

74
00:02:44,950 --> 00:02:46,360
main activity we're going to cut all the

75
00:02:46,360 --> 00:02:48,760
code out from the companion object from

76
00:02:48,760 --> 00:02:53,170
the Declaration right through down to

77
00:02:53,170 --> 00:02:55,690
the closing right tab curly brace

78
00:02:55,690 --> 00:02:58,120
leaving just the companion line there

79
00:02:58,120 --> 00:02:59,860
and I'm going to take the opportunity to

80
00:02:59,860 --> 00:03:01,030
delete that as well cuz we won't be

81
00:03:01,030 --> 00:03:03,040
needing that anymore I'm going to paste

82
00:03:03,040 --> 00:03:06,040
that in the download data class that we

83
00:03:06,040 --> 00:03:08,319
just created and that's when I got to

84
00:03:08,319 --> 00:03:09,700
paste it we've got a lump of imports

85
00:03:09,700 --> 00:03:11,560
that I've actually popped up now in this

86
00:03:11,560 --> 00:03:13,569
case we don't want to import Android

87
00:03:13,569 --> 00:03:15,549
widgets on this view so I'm gonna

88
00:03:15,549 --> 00:03:17,530
unselect that one from the list and

89
00:03:17,530 --> 00:03:19,540
obviously that's a UI related thing

90
00:03:19,540 --> 00:03:21,430
which is why we're not including it okay

91
00:03:21,430 --> 00:03:24,190
okay we've got that you know paste it in

92
00:03:24,190 --> 00:03:27,340
to our downloaded data class this is a

93
00:03:27,340 --> 00:03:30,790
basic async class and we you shouldn't

94
00:03:30,790 --> 00:03:33,310
have to make too many changes to it what

95
00:03:33,310 --> 00:03:34,690
I'll do you I'll start off by doing is

96
00:03:34,690 --> 00:03:38,079
pasting or moving the tag to the top

97
00:03:38,079 --> 00:03:39,670
level and make it a costs let's go ahead

98
00:03:39,670 --> 00:03:45,579
and do that and that should be Const now

99
00:03:45,579 --> 00:03:47,350
also we won't need a context for the

100
00:03:47,350 --> 00:03:51,640
definition here or reference to the

101
00:03:51,640 --> 00:03:52,209
ListView

102
00:03:52,209 --> 00:03:53,950
in fact this class shouldn't have any

103
00:03:53,950 --> 00:03:55,870
knowledge about the UI it's just going

104
00:03:55,870 --> 00:03:58,600
to download and parse the data now it

105
00:03:58,600 --> 00:04:00,880
will need to know what created it to

106
00:04:00,880 --> 00:04:02,109
call it back when the data is available

107
00:04:02,109 --> 00:04:04,750
and it shouldn't be marked private so

108
00:04:04,750 --> 00:04:06,569
I'm going to delete that out for now

109
00:04:06,569 --> 00:04:08,530
change the definition so it's no longer

110
00:04:08,530 --> 00:04:11,109
private then within the parentheses

111
00:04:11,109 --> 00:04:12,819
we're going to be using an interface

112
00:04:12,819 --> 00:04:14,950
method to call back on and we'll write

113
00:04:14,950 --> 00:04:16,539
that after the declaration but let's in

114
00:04:16,539 --> 00:04:20,019
print parentheses add private val call

115
00:04:20,019 --> 00:04:21,548
back :

116
00:04:21,548 --> 00:04:24,570
I'll call it downloader call back

117
00:04:24,570 --> 00:04:27,340
leaving everything else s is callback

118
00:04:27,340 --> 00:04:29,110
will be the object that created the

119
00:04:29,110 --> 00:04:30,850
download data instance

120
00:04:30,850 --> 00:04:32,440
and we'll implement a function that we

121
00:04:32,440 --> 00:04:34,450
can call so we'll get to the interface

122
00:04:34,450 --> 00:04:37,240
shortly but what we can do now is remove

123
00:04:37,240 --> 00:04:39,760
the two var declarations up here because

124
00:04:39,760 --> 00:04:40,810
we're going to replace those in our

125
00:04:40,810 --> 00:04:43,450
interface with our interface we're also

126
00:04:43,450 --> 00:04:45,310
going to delete the init block there as

127
00:04:45,310 --> 00:04:49,870
well all right so I'll go ahead now and

128
00:04:49,870 --> 00:04:54,280
add our interface so interface and it's

129
00:04:54,280 --> 00:04:57,520
download a callback then add a left or

130
00:04:57,520 --> 00:04:59,440
right curly brace there's going to be

131
00:04:59,440 --> 00:05:01,870
fun we can add a function fun it's going

132
00:05:01,870 --> 00:05:06,670
to be on data available parentheses data

133
00:05:06,670 --> 00:05:09,220
: and we're going to find this a list of

134
00:05:09,220 --> 00:05:11,380
feed entry objects and lists and then a

135
00:05:11,380 --> 00:05:13,240
diamond and there's going to be feed

136
00:05:13,240 --> 00:05:17,970
entry alright so that's how it defines

137
00:05:17,970 --> 00:05:20,650
so we've now got errors in the on post

138
00:05:20,650 --> 00:05:23,110
execute function when we try to refer to

139
00:05:23,110 --> 00:05:24,760
things like the adapter in the list view

140
00:05:24,760 --> 00:05:26,890
again this class isn't concerned about

141
00:05:26,890 --> 00:05:28,600
the UI it's just you know it just

142
00:05:28,600 --> 00:05:31,300
downloads and passes the data and sends

143
00:05:31,300 --> 00:05:32,830
the result back so what I'm going to do

144
00:05:32,830 --> 00:05:35,590
is replace the code with a call to the

145
00:05:35,590 --> 00:05:38,170
calling classes on data available

146
00:05:38,170 --> 00:05:39,550
section let's go ahead and clean that up

147
00:05:39,550 --> 00:05:42,570
a bit so I'm going to delete this super

148
00:05:42,570 --> 00:05:45,460
and I believe the other tag entry that

149
00:05:45,460 --> 00:05:47,770
we had there what we're also going to do

150
00:05:47,770 --> 00:05:50,680
is only pass the data if result isn't an

151
00:05:50,680 --> 00:05:52,510
empty string so on the line after the

152
00:05:52,510 --> 00:05:54,610
VAR pars applications we'll do a test

153
00:05:54,610 --> 00:05:55,150
for that

154
00:05:55,150 --> 00:05:58,300
if parentheses result is not empty so

155
00:05:58,300 --> 00:06:01,210
dot is not empty closing your

156
00:06:01,210 --> 00:06:04,240
parentheses at a code block then and

157
00:06:04,240 --> 00:06:06,130
only then when we do a pause and stop

158
00:06:06,130 --> 00:06:10,090
pars result I could have just copied

159
00:06:10,090 --> 00:06:11,260
that line there so I'm going to delete

160
00:06:11,260 --> 00:06:13,480
that now again we're not concerned with

161
00:06:13,480 --> 00:06:15,220
the UI so we're going to delete these

162
00:06:15,220 --> 00:06:16,870
two lines here we don't want to want to

163
00:06:16,870 --> 00:06:19,570
be updating the user interface here

164
00:06:19,570 --> 00:06:20,830
instead what we're going to do is just

165
00:06:20,830 --> 00:06:22,750
add that callback as I mentioned so

166
00:06:22,750 --> 00:06:25,960
callback dot on data available we're

167
00:06:25,960 --> 00:06:27,580
going to parse applications or paths

168
00:06:27,580 --> 00:06:31,110
sparse applications dot applications

169
00:06:31,110 --> 00:06:33,640
looking further down there the doing

170
00:06:33,640 --> 00:06:35,590
background function is fine but that's

171
00:06:35,590 --> 00:06:37,300
been making quite a significant change

172
00:06:37,300 --> 00:06:39,250
to the app structure what I'm going to

173
00:06:39,250 --> 00:06:41,860
do is rename all the logging there it is

174
00:06:41,860 --> 00:06:43,150
useful to check that the function has

175
00:06:43,150 --> 00:06:44,770
been called

176
00:06:44,770 --> 00:06:47,500
I'll just move that back and at this

177
00:06:47,500 --> 00:06:49,660
point we're done with the modifications

178
00:06:49,660 --> 00:06:52,450
for this class but one thing I do want

179
00:06:52,450 --> 00:06:54,340
to show you and what we need to change

180
00:06:54,340 --> 00:06:56,620
is when we initially talked about and

181
00:06:56,620 --> 00:06:58,750
set up this download XML function or

182
00:06:58,750 --> 00:07:00,460
showing you how simple it was to do that

183
00:07:00,460 --> 00:07:02,950
I did leave out the error handling we

184
00:07:02,950 --> 00:07:04,480
had enough to concentrate on at the time

185
00:07:04,480 --> 00:07:06,640
but now is a good opportunity to add

186
00:07:06,640 --> 00:07:08,530
that back again so let's go ahead and do

187
00:07:08,530 --> 00:07:11,080
that this is the download XML function

188
00:07:11,080 --> 00:07:13,240
so I'm gonna start here by adding things

189
00:07:13,240 --> 00:07:14,830
to a try block here so it's gonna be try

190
00:07:14,830 --> 00:07:17,950
left curly brace and I'm gonna indent

191
00:07:17,950 --> 00:07:19,710
the return there they'll have a closing

192
00:07:19,710 --> 00:07:22,420
right curly brace then we need to catch

193
00:07:22,420 --> 00:07:24,790
some exceptions so we'll start with a

194
00:07:24,790 --> 00:07:27,670
catched ecole and we'll start with

195
00:07:27,670 --> 00:07:31,570
malformed at URL exception so if you get

196
00:07:31,570 --> 00:07:34,080
that we're gonna do a log d parentheses

197
00:07:34,080 --> 00:07:40,590
tag comma download XML colon invalid

198
00:07:40,590 --> 00:07:43,960
euro and closing double quote +

199
00:07:43,960 --> 00:07:47,380
e.message so that's our first one next

200
00:07:47,380 --> 00:07:49,750
what I'm going to do is annoy exception

201
00:07:49,750 --> 00:07:54,910
so catch e : hi our exception same do

202
00:07:54,910 --> 00:07:57,070
there with the log log D you could do

203
00:07:57,070 --> 00:07:59,140
and logged on either but for debug

204
00:07:59,140 --> 00:08:00,820
purposes I'm going to leave the log D in

205
00:08:00,820 --> 00:08:02,140
there because that'll become useful a

206
00:08:02,140 --> 00:08:05,740
few videos time so log D parenthesis tag

207
00:08:05,740 --> 00:08:11,710
comma and download XML again just home

208
00:08:11,710 --> 00:08:14,710
IO exception reading data is it getting

209
00:08:14,710 --> 00:08:16,960
the error message then we'll let our

210
00:08:16,960 --> 00:08:19,060
plus e dot message on the end again so

211
00:08:19,060 --> 00:08:20,260
you get more details about what the

212
00:08:20,260 --> 00:08:22,660
exception was I need to change that

213
00:08:22,660 --> 00:08:25,000
reference to a lock I see there and the

214
00:08:25,000 --> 00:08:26,530
third exception we want to catch is a

215
00:08:26,530 --> 00:08:29,710
security exception e : security

216
00:08:29,710 --> 00:08:33,750
exception log D parentheses ter comma

217
00:08:33,750 --> 00:08:38,320
there's gonna be download XML : security

218
00:08:38,320 --> 00:08:42,429
exception and we'll ask the question

219
00:08:42,429 --> 00:08:45,160
needs permission question mark then

220
00:08:45,160 --> 00:08:50,170
double quote + e dot message and what

221
00:08:50,170 --> 00:08:51,250
you could do there as you can do an e

222
00:08:51,250 --> 00:08:52,870
dot print stack trace if you wanted to

223
00:08:52,870 --> 00:08:54,940
and done uppercase e there again

224
00:08:54,940 --> 00:08:57,520
eat up print stack trace but I'll

225
00:08:57,520 --> 00:08:58,450
actually comment it out for

226
00:08:58,450 --> 00:09:00,310
now then one other thing we need to do

227
00:09:00,310 --> 00:09:01,930
here though because we haven't closed

228
00:09:01,930 --> 00:09:05,140
that in the Tri we need to return an

229
00:09:05,140 --> 00:09:06,550
empty string in fact if there was an

230
00:09:06,550 --> 00:09:08,290
exception so down here we little

231
00:09:08,290 --> 00:09:11,530
returned an empty string and we just

232
00:09:11,530 --> 00:09:14,110
make a quick note about that turn an

233
00:09:14,110 --> 00:09:17,350
empty string if there was an exception

234
00:09:17,350 --> 00:09:21,670
now what I would like to do is tidy up

235
00:09:21,670 --> 00:09:23,830
these nullable parameters in the two

236
00:09:23,830 --> 00:09:26,020
functions if we end up passing a null

237
00:09:26,020 --> 00:09:28,330
string for the URL that's an error in

238
00:09:28,330 --> 00:09:30,370
our code so I'd rather the app pressures

239
00:09:30,370 --> 00:09:32,350
quickly so that we can detect the

240
00:09:32,350 --> 00:09:34,150
problem in testing so for the doing

241
00:09:34,150 --> 00:09:36,010
background I'm going to try to remove

242
00:09:36,010 --> 00:09:40,120
the safe call operator there and also do

243
00:09:40,120 --> 00:09:44,130
the same for our download XML function

244
00:09:44,130 --> 00:09:46,600
download XML is our function so we're

245
00:09:46,600 --> 00:09:48,220
obviously free to modify that one all we

246
00:09:48,220 --> 00:09:50,320
want that doing background function you

247
00:09:50,320 --> 00:09:52,240
may remember what's generated for us in

248
00:09:52,240 --> 00:09:55,150
Android studio used a nullable type but

249
00:09:55,150 --> 00:09:57,010
our async task if you come up and have a

250
00:09:57,010 --> 00:09:58,750
look at that again that we've defined on

251
00:09:58,750 --> 00:10:02,650
line 15 doesn't use nullable types so if

252
00:10:02,650 --> 00:10:04,300
you're passing multiple values in an

253
00:10:04,300 --> 00:10:06,460
array then it may well be wise to leave

254
00:10:06,460 --> 00:10:09,160
the virag parameter as an array of a

255
00:10:09,160 --> 00:10:11,500
nullable objects and perform an old test

256
00:10:11,500 --> 00:10:13,390
inside doing background I'm not

257
00:10:13,390 --> 00:10:14,950
suggesting that you always remove that

258
00:10:14,950 --> 00:10:17,290
question mark but it is safe to do so

259
00:10:17,290 --> 00:10:19,720
here all right so that's our download

260
00:10:19,720 --> 00:10:21,820
data class finished in the next video

261
00:10:21,820 --> 00:10:23,590
we'll swing over and start working on

262
00:10:23,590 --> 00:10:25,660
our view model so I'll see you in the

263
00:10:25,660 --> 00:10:28,080
next video

