1
00:00:04,660 --> 00:00:07,930
Alright, so going on to the solution to

2
00:00:07,930 --> 00:00:09,280
the challenge that we talked about at

3
00:00:09,280 --> 00:00:11,230
the end of the last video, the first

4
00:00:11,230 --> 00:00:12,820
thing that we're going to do is add the

5
00:00:12,820 --> 00:00:15,339
refresh option to the menu. Now that's

6
00:00:15,339 --> 00:00:16,869
very simple - we're just going to drag a new

7
00:00:16,869 --> 00:00:19,630
item into the Design, to make sure that

8
00:00:19,630 --> 00:00:21,070
it's below the group and not a member of

9
00:00:21,070 --> 00:00:22,900
it. And we talked about that previously,

10
00:00:22,900 --> 00:00:27,789
so Menu Item, and you can either do it

11
00:00:27,789 --> 00:00:30,010
here or come down here. So it's easy to

12
00:00:30,010 --> 00:00:31,359
do it down here, in the Component Tree

13
00:00:31,359 --> 00:00:33,460
usually. And you can see there, that I've

14
00:00:33,460 --> 00:00:35,080
dragged it so it's actually in the wrong

15
00:00:35,080 --> 00:00:37,840
place, but I can move that out to make

16
00:00:37,840 --> 00:00:40,059
sure that it's no longer in the menu

17
00:00:40,059 --> 00:00:42,280
anymore, and no longer in the menu group

18
00:00:42,280 --> 00:00:45,250
anymore, which is what we want here. Next

19
00:00:45,250 --> 00:00:48,070
we want to change the ID. the ID is going

20
00:00:48,070 --> 00:00:54,100
to be a mnuRefresh, and the title, we'll

21
00:00:54,100 --> 00:00:57,460
make Refresh. Alright, so that's it for

22
00:00:57,460 --> 00:01:05,640
the menu and we'll go back to the code.

23
00:01:05,640 --> 00:01:08,770
Alright, so if we're going to track the URL, so

24
00:01:08,770 --> 00:01:10,420
that we can compare the previous one to

25
00:01:10,420 --> 00:01:11,500
the one that we're about to download,

26
00:01:11,500 --> 00:01:13,929
then we need a variable to store it in.

27
00:01:13,929 --> 00:01:16,479
Now we're also going to be storing the

28
00:01:16,479 --> 00:01:18,550
URL and Limit in a Bundle, so I'm going

29
00:01:18,550 --> 00:01:21,160
to define two constants to use as the keys.

30
00:01:21,160 --> 00:01:22,959
So I'm going to do that at the top of

31
00:01:22,959 --> 00:01:26,679
MainActivity, just below the feedLimit

32
00:01:26,679 --> 00:01:28,630
and feedUrl that we worked on in the

33
00:01:28,630 --> 00:01:30,940
last two videos. So we start with a

34
00:01:30,940 --> 00:01:38,979
private var feedCachedUrl is equal

35
00:01:38,979 --> 00:01:41,200
to, and we'll start with double quotes

36
00:01:41,200 --> 00:01:47,170
invalidated. Then private val STATE

37
00:01:47,170 --> 00:01:53,670
_URL is equal to feedUrl. Then

38
00:01:53,670 --> 00:01:58,060
private val STATE_LIMIT

39
00:01:58,060 --> 00:02:03,520
equals feedLimit. Now I've initialized

40
00:02:03,520 --> 00:02:06,700
the feedCachedUrl String to a value that

41
00:02:06,700 --> 00:02:09,669
can't possibly be a valid URL. Now

42
00:02:09,669 --> 00:02:11,260
anytime we want to force a download to

43
00:02:11,260 --> 00:02:13,660
happen, such as when the Refresh option

44
00:02:13,660 --> 00:02:15,880
is chosen from the menu, we just need to

45
00:02:15,880 --> 00:02:17,930
set it to some value that isn't a

46
00:02:17,930 --> 00:02:19,969
URL. Now anything would do, but I've

47
00:02:19,969 --> 00:02:22,700
just used the word INVALIDATED. Now to

48
00:02:22,700 --> 00:02:24,140
prevent the same URL from being

49
00:02:24,140 --> 00:02:25,609
downloaded unnecessarily,

50
00:02:25,609 --> 00:02:28,010
we just need to compare the cached URL

51
00:02:28,010 --> 00:02:30,140
value with the one that we're about to

52
00:02:30,140 --> 00:02:32,120
download. Now if they're the same, there's

53
00:02:32,120 --> 00:02:34,549
no need to download again. So let's go

54
00:02:34,549 --> 00:02:37,310
down to the downloadUrl function to

55
00:02:37,310 --> 00:02:43,430
do that. So down here, we're going to wrap

56
00:02:43,430 --> 00:02:45,109
this in some code, so we're going to put an

57
00:02:45,109 --> 00:02:49,459
if test here to say if parentheses feed

58
00:02:49,459 --> 00:02:55,480
Url is not equal to feedCachedUrl.

59
00:02:55,480 --> 00:02:57,769
We're going to wrap that code so we're

60
00:02:57,769 --> 00:03:00,650
going to copy this code, paste it in

61
00:03:00,650 --> 00:03:04,549
there. Okay, and I'm going to then put an

62
00:03:04,549 --> 00:03:09,040
else in there, so else Log.d

63
00:03:09,040 --> 00:03:16,939
parentheses TAG comma downloadUrl - URL

64
00:03:16,939 --> 00:03:21,560
not changed. So now with that code, when

65
00:03:21,560 --> 00:03:24,319
downloadUrl's called, it first checks

66
00:03:24,319 --> 00:03:26,419
the URL it's given against the stored

67
00:03:26,419 --> 00:03:28,639
value. Now if they're the same, then

68
00:03:28,639 --> 00:03:29,810
there's no need to download the data

69
00:03:29,810 --> 00:03:32,569
again - it just logs the fact so that we

70
00:03:32,569 --> 00:03:33,859
can see the code working in the logcat.

71
00:03:33,859 --> 00:03:36,229
But of course, if the URL's are different,

72
00:03:36,229 --> 00:03:37,400
then it's going to go through and execute

73
00:03:37,400 --> 00:03:40,189
normally. And importantly, the other thing

74
00:03:40,189 --> 00:03:41,840
we need to do is, we need to update the

75
00:03:41,840 --> 00:03:45,379
value at the end of that; feedCachedUrl

76
00:03:45,379 --> 00:03:50,540
is equal to feedUrl. So basically, after

77
00:03:50,540 --> 00:03:52,069
downloading the data as usual, we're

78
00:03:52,069 --> 00:03:53,540
storing the URL that's just been

79
00:03:53,540 --> 00:03:56,150
downloaded in the feedCachedUrl field,

80
00:03:56,150 --> 00:03:59,120
ready to be compared next time. Alright,

81
00:03:59,120 --> 00:04:02,599
so onto the Refresh menu option. Now all

82
00:04:02,599 --> 00:04:05,930
that has to do, is set feedCachedUrl to

83
00:04:05,930 --> 00:04:08,599
something different to the last URL. So

84
00:04:08,599 --> 00:04:09,799
that's pretty straightforward. So let's

85
00:04:09,799 --> 00:04:11,720
have a look at the option there - the

86
00:04:11,720 --> 00:04:14,930
onOptionsItemSelected. We're going to use

87
00:04:14,930 --> 00:04:16,548
the string INVALIDATED because we've

88
00:04:16,548 --> 00:04:18,529
used that before. So we're going to put

89
00:04:18,529 --> 00:04:20,870
this code here, outside of the R.

90
00:04:20,870 --> 00:04:23,509
id.mnu 10 and mnu 25 tests.

91
00:04:23,509 --> 00:04:29,120
R.id.mnuRefresh, arrow

92
00:04:29,120 --> 00:04:32,310
token. We're gonna put feedCachedUrl

93
00:04:32,310 --> 00:04:37,680
equals INVALIDATE. Alright, so I'm

94
00:04:37,680 --> 00:04:39,180
using that string INVALIDATE, well

95
00:04:39,180 --> 00:04:41,250
actually, INVALIDATED to be consistent. So

96
00:04:41,250 --> 00:04:43,500
using that string again, as that helps to

97
00:04:43,500 --> 00:04:45,719
document what we're doing. So the feedCached

98
00:04:45,719 --> 00:04:47,310
Url has been invalidated,

99
00:04:47,310 --> 00:04:49,080
so the download will then need to

100
00:04:49,080 --> 00:04:52,349
be performed again. Alright, so

101
00:04:52,349 --> 00:04:53,490
that's one part of the challenge

102
00:04:53,490 --> 00:04:56,069
completed. The app should now - shouldn't

103
00:04:56,069 --> 00:04:58,500
now - download the data again, if we select

104
00:04:58,500 --> 00:05:00,990
the same menu item again. So it's worth

105
00:05:00,990 --> 00:05:02,550
testing the app, at this point, to make

106
00:05:02,550 --> 00:05:05,039
sure the code works. If you leave testing

107
00:05:05,039 --> 00:05:06,960
until you've made loads of changes, it

108
00:05:06,960 --> 00:05:09,659
gets much harder to find bugs. You've got

109
00:05:09,659 --> 00:05:11,909
far more code to check through. Running

110
00:05:11,909 --> 00:05:13,469
your app after making each change is a

111
00:05:13,469 --> 00:05:15,389
good habit to get into, and really

112
00:05:15,389 --> 00:05:17,610
does make debugging a lot easier. So

113
00:05:17,610 --> 00:05:23,069
let's actually run this. I'm going to go

114
00:05:23,069 --> 00:05:29,520
back to portrait mode.

115
00:05:29,520 --> 00:05:32,819
Alright, so far. so good. The app loads

116
00:05:32,819 --> 00:05:34,380
the first URL fine, so that's a good

117
00:05:34,380 --> 00:05:34,770
start.

118
00:05:34,770 --> 00:05:37,410
So just to confirm that the menu still

119
00:05:37,410 --> 00:05:38,940
works, we'll try doing a different type -

120
00:05:38,940 --> 00:05:42,210
we'll do Songs. Well that still works - we

121
00:05:42,210 --> 00:05:44,370
still get the top 10 songs. Alright, I'm gonna

122
00:05:44,370 --> 00:05:47,280
open the logcat, and we're going to do a

123
00:05:47,280 --> 00:05:50,340
search, or we're going to, rather, select the

124
00:05:50,340 --> 00:05:53,910
same option again - Songs - and you can see

125
00:05:53,910 --> 00:05:55,729
here in the logcat;

126
00:05:55,729 --> 00:05:59,370
downloadUrl - URL not changed. So that's

127
00:05:59,370 --> 00:06:01,590
working as well. So things seem to be

128
00:06:01,590 --> 00:06:03,210
working pretty good, but to make sure

129
00:06:03,210 --> 00:06:05,430
that the app still uses the same URL and

130
00:06:05,430 --> 00:06:07,680
feed limit, after being rotated, we need

131
00:06:07,680 --> 00:06:09,930
to store the values of the URL and the

132
00:06:09,930 --> 00:06:11,849
feedLimit, when the Activity is

133
00:06:11,849 --> 00:06:13,860
destroyed. So let's go back add

134
00:06:13,860 --> 00:06:17,490
the code for that. And what I'm going to

135
00:06:17,490 --> 00:06:19,889
do is just put the cursor below the on

136
00:06:19,889 --> 00:06:23,360
OptionsItemSelected method function,

137
00:06:23,360 --> 00:06:26,009
and let's get Android Studio to

138
00:06:26,009 --> 00:06:27,930
generate the onSaveInstanceState

139
00:06:27,930 --> 00:06:30,389
function. So I'm going to do my Ctrl-O,

140
00:06:30,389 --> 00:06:33,870
and we want onSaveInstanceState.

141
00:06:33,870 --> 00:06:35,729
Now, remembering there's two versions

142
00:06:35,729 --> 00:06:37,710
of this function. We want the one 

143
00:06:37,710 --> 00:06:39,240
that's just got a single parameter. That

144
00:06:39,240 --> 00:06:40,409
we're looking at currently - that's got

145
00:06:40,409 --> 00:06:41,639
two options, so I'm gonna press the down

146
00:06:41,639 --> 00:06:43,199
arrow to go to the second one with the

147
00:06:43,199 --> 00:06:45,710
single parameter. Press Enter.

148
00:06:45,710 --> 00:06:48,120
Alright, I've added that

149
00:06:48,120 --> 00:06:50,070
between the onOptionsItemSelected

150
00:06:50,070 --> 00:06:53,250
and onDestroy, so that onDestroy ends up

151
00:06:53,250 --> 00:06:56,909
being the last function in the class. So

152
00:06:56,909 --> 00:06:58,440
we're going to now write some code in

153
00:06:58,440 --> 00:06:59,630
there. So we're going to start by

154
00:06:59,630 --> 00:07:02,900
removing the question mark from Bundle.

155
00:07:02,900 --> 00:07:05,099
We're going to leave the super dot

156
00:07:05,099 --> 00:07:07,740
onSaveInstanceState line in. We're going

157
00:07:07,740 --> 00:07:14,639
to put outState.putString, and it's

158
00:07:14,639 --> 00:07:17,930
going to be STATE_URL comma

159
00:07:17,930 --> 00:07:22,500
then feedUrl. Then on the next line, out

160
00:07:22,500 --> 00:07:27,180
State.putString STATE_

161
00:07:27,180 --> 00:07:31,919
LIMIT, feedLimit - and that shouldn't be

162
00:07:31,919 --> 00:07:34,500
a string, it should be an int. Let's

163
00:07:34,500 --> 00:07:35,699
change that to an it because, of course,

164
00:07:35,699 --> 00:07:39,630
feedLimit is a number. Okay, that fixes

165
00:07:39,630 --> 00:07:41,760
that. Now we saw code like that before, in

166
00:07:41,760 --> 00:07:42,990
the calculator app - it just

167
00:07:42,990 --> 00:07:44,430
stores our two fields so that we can

168
00:07:44,430 --> 00:07:46,590
call them back again, when the Activity's

169
00:07:46,590 --> 00:07:49,410
recreated. Now the bundle's passed in as a

170
00:07:49,410 --> 00:07:51,540
nullable type, but we know that it won't

171
00:07:51,540 --> 00:07:54,390
be null, and as a result, I changed the

172
00:07:54,390 --> 00:07:56,610
function signature by removing the

173
00:07:56,610 --> 00:07:59,250
question mark after Bundle. Now remember

174
00:07:59,250 --> 00:08:01,800
that data's stored in a Bundle using

175
00:08:01,800 --> 00:08:04,740
key/value pairs. We specify a key when

176
00:08:04,740 --> 00:08:06,870
saving something, and use the same key to

177
00:08:06,870 --> 00:08:08,730
get it back again. And we'll see that

178
00:08:08,730 --> 00:08:11,370
our two keys; STATE_URL and

179
00:08:11,370 --> 00:08:13,680
STATE_LIMIT, being used again

180
00:08:13,680 --> 00:08:16,320
when we retrieve the values shortly. Now

181
00:08:16,320 --> 00:08:17,880
when we saved and restored values

182
00:08:17,880 --> 00:08:20,550
previously, we used the onRestore

183
00:08:20,550 --> 00:08:21,990
InstanceState and function.

184
00:08:21,990 --> 00:08:24,180
Now in that app, though, we weren't doing

185
00:08:24,180 --> 00:08:25,980
anything in onCreate, other than

186
00:08:25,980 --> 00:08:28,650
inflating the calculator layout. So it's

187
00:08:28,650 --> 00:08:30,480
probably a good idea just to review the

188
00:08:30,480 --> 00:08:33,419
Activity Lifecycle. Alright, so on

189
00:08:33,419 --> 00:08:35,480
RestoreInstanceState is called after

190
00:08:35,480 --> 00:08:39,030
the onCreate method. However, we do the

191
00:08:39,030 --> 00:08:41,700
initial download in onCreate. So when the

192
00:08:41,700 --> 00:08:44,070
device is rotated, we need to retrieve

193
00:08:44,070 --> 00:08:46,370
the saved Bundle in the onCreate method,

194
00:08:46,370 --> 00:08:49,170
rather than in onRestoreInstanceState,

195
00:08:49,170 --> 00:08:51,210
because if we wait for onRestore

196
00:08:51,210 --> 00:08:52,830
InstanceState, we won't have the URL

197
00:08:52,830 --> 00:08:55,530
available when we need it. Alright, so

198
00:08:55,530 --> 00:08:57,120
when the Activity's first launched, there

199
00:08:57,120 --> 00:08:59,460
won't be a Bundle. But if the Activity's

200
00:08:59,460 --> 00:09:02,280
restarted because of device rotation, for

201
00:09:02,280 --> 00:09:04,500
example, then the Bundle passed to

202
00:09:04,500 --> 00:09:06,900
onCreate will be non-null, and we can restore

203
00:09:06,900 --> 00:09:08,970
our fields there. So let's actually write

204
00:09:08,970 --> 00:09:11,130
some code now, in the onCreate method, to

205
00:09:11,130 --> 00:09:14,430
achieve this. So there's our onCreate

206
00:09:14,430 --> 00:09:15,660
method and we're going to put some code

207
00:09:15,660 --> 00:09:18,300
after the last logging. Well, actually,

208
00:09:18,300 --> 00:09:20,010
what we'll do is we'll put it after the

209
00:09:20,010 --> 00:09:23,130
start. So we've got the super.on

210
00:09:23,130 --> 00:09:26,490
Create and the setContentView. We'll put

211
00:09:26,490 --> 00:09:28,790
another log entry there, Log.d

212
00:09:28,790 --> 00:09:35,490
TAG parentheses onCreate called, and

213
00:09:35,490 --> 00:09:36,570
then we're going to put our code in here;

214
00:09:36,570 --> 00:09:40,470
if parentheses savedInstanceState is

215
00:09:40,470 --> 00:09:44,460
not equal to null. Add the code block, then

216
00:09:44,460 --> 00:09:47,700
we're going to put feedUrl is equal to

217
00:09:47,700 --> 00:09:52,620
savedInstanceState.getString. Then it's

218
00:09:52,620 --> 00:09:55,340
going to STATE_URL. Then it's going to

219
00:09:55,340 --> 00:09:59,660
be feedLimit is equal to savedInstance

220
00:09:59,660 --> 00:10:04,550
State.getInt STATE_

221
00:10:04,550 --> 00:10:09,860
limit. Now when we're dealing with the

222
00:10:09,860 --> 00:10:12,140
Bundle in onCreate, we have to cater

223
00:10:12,140 --> 00:10:14,180
for it being null, and that's because it

224
00:10:14,180 --> 00:10:16,190
definitely will be, at least some of the

225
00:10:16,190 --> 00:10:18,860
time. Now I know Kotlin tries to do away

226
00:10:18,860 --> 00:10:20,630
with null checks but sometimes they're

227
00:10:20,630 --> 00:10:23,690
valid, even in Kotlin. So here, null is a

228
00:10:23,690 --> 00:10:26,570
valid value for the Bundle. It signifies

229
00:10:26,570 --> 00:10:28,820
that there's nothing to restore. Now

230
00:10:28,820 --> 00:10:30,350
because we've performed a null check,

231
00:10:30,350 --> 00:10:33,589
Kotlin can perform a smart cast. So saved

232
00:10:33,589 --> 00:10:36,350
InstanceState is cast to be an non-null

233
00:10:36,350 --> 00:10:38,630
Bundle, and we don't have to use the safe

234
00:10:38,630 --> 00:10:40,610
call operator when accessing the get

235
00:10:40,610 --> 00:10:43,610
String and getInt methods. Alright, so

236
00:10:43,610 --> 00:10:44,930
we're now ready to test the program to

237
00:10:44,930 --> 00:10:46,670
make sure it meets all the requirements

238
00:10:46,670 --> 00:10:48,980
of the challenge. So let's actually run

239
00:10:48,980 --> 00:10:51,140
this again. Actually, what I'll do is open up

240
00:10:51,140 --> 00:10:56,690
logcat and run it. If logcat doesn't

241
00:10:56,690 --> 00:10:57,890
clear for you, then you'll want to have

242
00:10:57,890 --> 00:10:59,120
cleared it, but you can see, in my

243
00:10:59,120 --> 00:11:00,410
case, it did and then we've got the data -

244
00:11:00,410 --> 00:11:03,530
we've got the logcat showing. So

245
00:11:03,530 --> 00:11:05,390
let's first check a few URLs with

246
00:11:05,390 --> 00:11:07,339
different limits, to make sure we haven't

247
00:11:07,339 --> 00:11:09,470
broken anything that was working. So

248
00:11:09,470 --> 00:11:14,480
I'm gonna go back to the emulator. So we've

249
00:11:14,480 --> 00:11:16,310
got the Top 10 feeds in there, so that's

250
00:11:16,310 --> 00:11:18,320
a good start, and you can see that we've

251
00:11:18,320 --> 00:11:22,740
got the 10 entries in there.

252
00:11:22,740 --> 00:11:25,080
Okay, so that's working alright. Let's now

253
00:11:25,080 --> 00:11:29,510
change that and go for a limit of 25.

254
00:11:29,510 --> 00:11:32,750
Okay, clearly we've got more apps showing

255
00:11:32,750 --> 00:11:34,580
here, so that's working okay as well -

256
00:11:34,580 --> 00:11:37,220
the Top 25. If I go ahead and choose

257
00:11:37,220 --> 00:11:40,460
Songs now, we should get 25 songs, and

258
00:11:40,460 --> 00:11:42,590
that's because the Top 25 was

259
00:11:42,590 --> 00:11:46,370
selected, so click on Songs. And what we

260
00:11:46,370 --> 00:11:49,100
can do is just do a filter for Main

261
00:11:49,100 --> 00:11:54,110
Activity. You can see that the feed

262
00:11:54,110 --> 00:11:55,730
limit was set to 25 and it hasn't been

263
00:11:55,730 --> 00:11:57,920
reset since. Now if we have a look at the

264
00:11:57,920 --> 00:12:00,500
songs, clearly there's more than 10 there.

265
00:12:00,500 --> 00:12:02,330
So that seems to be working nicely as

266
00:12:02,330 --> 00:12:04,220
well. And in terms of the URL, if we

267
00:12:04,220 --> 00:12:08,750
go back and remove the filter, we can see

268
00:12:08,750 --> 00:12:11,420
here by looking in the XML, that clearly

269
00:12:11,420 --> 00:12:14,060
that it's talking about albums and so

270
00:12:14,060 --> 00:12:15,770
forth. So clearly thats Songs, so that's

271
00:12:15,770 --> 00:12:18,740
correct. Now while we've got a Top 25 feed,

272
00:12:18,740 --> 00:12:21,740
it's a good point, or a good time, to rotate

273
00:12:21,740 --> 00:12:22,910
the device to make sure it doesn't

274
00:12:22,910 --> 00:12:25,070
revert to the default Top 10, that it was

275
00:12:25,070 --> 00:12:28,220
doing before. So let's go back and rotate

276
00:12:28,220 --> 00:12:37,010
now. So have a look. It looks to me, we've

277
00:12:37,010 --> 00:12:38,180
still got two heaps of songs there so

278
00:12:38,180 --> 00:12:39,620
everything seems to be working nicely as

279
00:12:39,620 --> 00:12:41,990
well - we've got 25 songs there. Now if I

280
00:12:41,990 --> 00:12:43,880
scroll down a little bit more, we can see

281
00:12:43,880 --> 00:12:45,440
that it's definitely still the songs, and

282
00:12:45,440 --> 00:12:46,700
we can see those on the screen anyway, so

283
00:12:46,700 --> 00:12:49,130
that's working nicely. Now if we go back

284
00:12:49,130 --> 00:12:56,210
and choose songs again, and we can just

285
00:12:56,210 --> 00:12:58,940
do a filter here - MainActivity again - we

286
00:12:58,940 --> 00:13:00,890
can see that downloadUrl, URL is not

287
00:13:00,890 --> 00:13:03,350
changed, which is correct. So that's

288
00:13:03,350 --> 00:13:05,030
looking good and now the last check is

289
00:13:05,030 --> 00:13:08,090
to check Songs again, to make sure that

290
00:13:08,090 --> 00:13:09,710
the data is re-downloaded when the

291
00:13:09,710 --> 00:13:11,210
same type of feed is selected for the

292
00:13:11,210 --> 00:13:18,220
second time. So let's try that - Songs,

293
00:13:18,220 --> 00:13:21,400
and again, download URL not changed. So

294
00:13:21,400 --> 00:13:22,480
that's looking good as well.

295
00:13:22,480 --> 00:13:24,640
Now you may well have solved the challenge

296
00:13:24,640 --> 00:13:26,440
in a different way, but if it passes

297
00:13:26,440 --> 00:13:29,050
these tests, then well done! And

298
00:13:29,050 --> 00:13:30,520
everything's working, so that's the end

299
00:13:30,520 --> 00:13:32,140
of this section. Well, we've actually

300
00:13:32,140 --> 00:13:34,300
covered quite a lot in this section; so

301
00:13:34,300 --> 00:13:37,330
we used an AsyncTask to download data

302
00:13:37,330 --> 00:13:39,550
without blocking the main UI thread, and

303
00:13:39,550 --> 00:13:43,150
also used the built-in HTTP classes to

304
00:13:43,150 --> 00:13:45,490
download data from the internet. Then we

305
00:13:45,490 --> 00:13:47,170
looked at the supplied XML parser

306
00:13:47,170 --> 00:13:49,780
classes to parse XML from the downloaded

307
00:13:49,780 --> 00:13:52,390
data, and store the values we wanted in

308
00:13:52,390 --> 00:13:55,090
our own objects. Now the ListView widget's

309
00:13:55,090 --> 00:13:56,920
designed for displaying lists of data,

310
00:13:56,920 --> 00:13:59,050
and we saw how to connect that to a

311
00:13:59,050 --> 00:14:01,390
basic adapter. We then went further and

312
00:14:01,390 --> 00:14:03,940
created our own custom adapter, to give

313
00:14:03,940 --> 00:14:05,440
more control over how the data's

314
00:14:05,440 --> 00:14:07,600
displayed in the ListView. And we

315
00:14:07,600 --> 00:14:09,520
finished by creating our own menus and

316
00:14:09,520 --> 00:14:11,740
menu groups, and writing code to respond

317
00:14:11,740 --> 00:14:13,600
to the different menu items being

318
00:14:13,600 --> 00:14:16,540
selected. Alright, so now you have a

319
00:14:16,540 --> 00:14:18,550
basic app, you can have a go at changing

320
00:14:18,550 --> 00:14:20,830
things to improve it. So some ideas you

321
00:14:20,830 --> 00:14:22,350
might want to try at this point are;

322
00:14:22,350 --> 00:14:24,670
adding some more of the Apple feeds, such

323
00:14:24,670 --> 00:14:27,460
as the Albums or New Releases feeds. You

324
00:14:27,460 --> 00:14:29,530
could try parsing out the feed title

325
00:14:29,530 --> 00:14:31,960
from the downloaded XML, and displaying

326
00:14:31,960 --> 00:14:34,570
that in a TextView above the list, so that

327
00:14:34,570 --> 00:14:36,190
users have a reminder of which view

328
00:14:36,190 --> 00:14:38,080
they're seing.  Perhaps you might want to

329
00:14:38,080 --> 00:14:40,120
try figuring out how to display the

330
00:14:40,120 --> 00:14:43,060
image URL in a text view, and searching

331
00:14:43,060 --> 00:14:44,410
on-line for how to make the links

332
00:14:44,410 --> 00:14:46,300
clickable, so that they open in the

333
00:14:46,300 --> 00:14:49,060
device's browser. Now it's helpful to

334
00:14:49,060 --> 00:14:51,100
watch these videos a few times, to really

335
00:14:51,100 --> 00:14:53,410
understand what's happening, and why we

336
00:14:53,410 --> 00:14:55,690
coded the app in this way. Now you'll

337
00:14:55,690 --> 00:14:57,220
find you pick up different things each

338
00:14:57,220 --> 00:14:59,740
time you watch the videos. Remember also,

339
00:14:59,740 --> 00:15:00,940
that there's a wealth of information

340
00:15:00,940 --> 00:15:03,490
available on-line, so if you're not sure

341
00:15:03,490 --> 00:15:05,230
how to do something, then a quick search

342
00:15:05,230 --> 00:15:07,180
will usually provide loads of

343
00:15:07,180 --> 00:15:09,460
information. Now the Google documentation

344
00:15:09,460 --> 00:15:11,830
is also very useful, even if most of the

345
00:15:11,830 --> 00:15:13,480
examples are currently written in Java,

346
00:15:13,480 --> 00:15:15,610
but I suspect over time, that will change

347
00:15:15,610 --> 00:15:17,950
and we'll start seeing Kotlin examples

348
00:15:17,950 --> 00:15:20,200
as well. So I'll stop the video here, and

349
00:15:20,200 --> 00:15:22,810
end this section, and in the next section

350
00:15:22,810 --> 00:15:24,250
we're going to create an app to view

351
00:15:24,250 --> 00:15:27,250
YouTube videos, using Google's YouTube

352
00:15:27,250 --> 00:15:31,530
API. See you in the next video.

