1 00:00:04,720 --> 00:00:06,610 Alright, we've now got our app 2 00:00:06,610 --> 00:00:09,370 downloading the RSS feed, but I mentioned 3 00:00:09,370 --> 00:00:11,110 previously that experienced Kotlin 4 00:00:11,110 --> 00:00:12,309 programmers will probably have been 5 00:00:12,309 --> 00:00:14,709 horrified by some of the code that we've 6 00:00:14,709 --> 00:00:17,170 created so far. What we've got is 7 00:00:17,170 --> 00:00:19,660 basically Java code, but written using 8 00:00:19,660 --> 00:00:21,970 Kotlin syntax. In fact, we could have 9 00:00:21,970 --> 00:00:23,620 pasted in the equivalent Java code 10 00:00:23,620 --> 00:00:25,540 and got Android Studio to convert it for 11 00:00:25,540 --> 00:00:27,970 us, and always there'd be a bit of 12 00:00:27,970 --> 00:00:29,530 tweaking needed but it would largely 13 00:00:29,530 --> 00:00:32,529 work. But that isn't how the downloadXML 14 00:00:32,529 --> 00:00:34,090 function would be written in Kotlin, 15 00:00:34,090 --> 00:00:35,710 though, so let's have a look at how we 16 00:00:35,710 --> 00:00:38,260 can tidy it up. So what I'm going to do is 17 00:00:38,260 --> 00:00:41,620 start with the catch blocks. Now at the 18 00:00:41,620 --> 00:00:44,079 moment, we've got four catch blocks, which 19 00:00:44,079 --> 00:00:46,420 all do just about the same 20 00:00:46,420 --> 00:00:48,879 thing - they log the error. Now apart from 21 00:00:48,879 --> 00:00:50,499 the stack trace for the security 22 00:00:50,499 --> 00:00:52,479 exception, the only difference is part of 23 00:00:52,479 --> 00:00:54,100 the stream that we're logging. Now we 24 00:00:54,100 --> 00:00:55,809 could put those individual pieces of 25 00:00:55,809 --> 00:00:58,269 text into a variable, and have a single 26 00:00:58,269 --> 00:01:00,370 logging call, but Kotlin allows 27 00:01:00,370 --> 00:01:02,079 us to handle things even better than 28 00:01:02,079 --> 00:01:04,420 that. So what I'm going to do is start by 29 00:01:04,420 --> 00:01:06,670 commenting out all the current catch 30 00:01:06,670 --> 00:01:11,110 blocks, and then what I'm going to do is 31 00:01:11,110 --> 00:01:13,030 type it in a more Kotlin-like way of 32 00:01:13,030 --> 00:01:15,100 dealing with them. So I'm going to come 33 00:01:15,100 --> 00:01:17,770 down - actually, what I'll do is, come 34 00:01:17,770 --> 00:01:25,150 down here. Then we'll do a catch, and in 35 00:01:25,150 --> 00:01:29,250 parentheses, e colon space exception, a 36 00:01:29,250 --> 00:01:33,690 code block, then we're gonna type val 37 00:01:33,690 --> 00:01:40,390 errorMessage colon string. Next line, 38 00:01:40,390 --> 00:01:44,250 when, e in parentheses and a code block. 39 00:01:44,250 --> 00:01:48,220 We're gonna type is MalformedURL 40 00:01:48,220 --> 00:01:52,360 Exception, then an arrow token, error 41 00:01:52,360 --> 00:02:00,960 Message equals downloadXML Invalid URL, 42 00:02:00,960 --> 00:02:02,590 dollar sign 43 00:02:02,590 --> 00:02:06,659 left and right curly braces, e.message. 44 00:02:06,659 --> 00:02:11,080 Then - and just fix up the typo there - error 45 00:02:11,080 --> 00:02:16,420 Message. Next line is IOException, the 46 00:02:16,420 --> 00:02:17,980 arrow token again, or 47 00:02:17,980 --> 00:02:19,510 the arrow, depending what you want to 48 00:02:19,510 --> 00:02:21,480 call it - it's got quite a few names out there - 49 00:02:21,480 --> 00:02:23,830 errorMessage equals. This time it's going 50 00:02:23,830 --> 00:02:29,230 to be downloadXML again, and IO 51 00:02:29,230 --> 00:02:35,769 exception reading data colon space and 52 00:02:35,769 --> 00:02:38,620 dollar sign, left and right curly braces, 53 00:02:38,620 --> 00:02:43,780 e.message again. Next line is Security 54 00:02:43,780 --> 00:02:47,049 Exception. We do this one slightly 55 00:02:47,049 --> 00:02:48,310 different so I'll have our arrow token 56 00:02:48,310 --> 00:02:50,650 again and then we're going to add a code 57 00:02:50,650 --> 00:02:53,670 block. we're going to start with e dot 58 00:02:53,670 --> 00:02:56,940 printStackTrace. Then on the next line, 59 00:02:56,940 --> 00:03:00,010 I'm going to put errormessage is 60 00:03:00,010 --> 00:03:06,190 equal to downloadXML : and this time it's a 61 00:03:06,190 --> 00:03:12,519 security Exception, and what Needs 62 00:03:12,519 --> 00:03:15,879 permission question mark and then we'll 63 00:03:15,879 --> 00:03:17,470 put the space and a dollar sign, left 64 00:03:17,470 --> 00:03:18,700 and right curly braces e.message 65 00:03:18,700 --> 00:03:22,750 again. And we'll close off that code block, 66 00:03:22,750 --> 00:03:25,329 and we'll end on the next line with else 67 00:03:25,329 --> 00:03:28,329 and the arrow token again, errorMessage 68 00:03:28,329 --> 00:03:35,349 is equal to Unknown error : dollar sign 69 00:03:35,349 --> 00:03:40,019 left and right curly braces, e.message. 70 00:03:40,019 --> 00:03:42,340 So now we've got a single catch block 71 00:03:42,340 --> 00:03:44,139 and we can test the type of the 72 00:03:44,139 --> 00:03:46,750 exception, using when. You can see that on 73 00:03:46,750 --> 00:03:49,840 line 85. Now we can improve that even 74 00:03:49,840 --> 00:03:51,700 further, and in fact, Android Studio is 75 00:03:51,700 --> 00:03:54,459 suggesting a way we can do that. So if I 76 00:03:54,459 --> 00:03:57,849 actually click on when, on line 85. Come 77 00:03:57,849 --> 00:03:59,260 over here, we get a tool tip - well 78 00:03:59,260 --> 00:04:00,280 actually, we can come over here and see 79 00:04:00,280 --> 00:04:01,870 the tooltip; Assignment can be lifted out 80 00:04:01,870 --> 00:04:04,419 of 'when'. What that means is that each of 81 00:04:04,419 --> 00:04:06,669 the cases inside the when block are 82 00:04:06,669 --> 00:04:09,280 assigned a string to errorMessage. Now 83 00:04:09,280 --> 00:04:11,319 many things in Kotlin can be used as 84 00:04:11,319 --> 00:04:14,139 either an expression or a statement. So 85 00:04:14,139 --> 00:04:15,250 we can use our when block as an 86 00:04:15,250 --> 00:04:17,139 expression and assign the result to error 87 00:04:17,139 --> 00:04:19,060 Message. So to show you what I mean, I can 88 00:04:19,060 --> 00:04:20,260 come over here now that I've actually 89 00:04:20,260 --> 00:04:22,570 selected when, click on this and click on 90 00:04:22,570 --> 00:04:26,229 Lift assignment out of when, and you can 91 00:04:26,229 --> 00:04:27,969 see that's made that far more concise as 92 00:04:27,969 --> 00:04:30,219 well. And we can even remove the 93 00:04:30,219 --> 00:04:31,660 declaration on line 94 00:04:31,660 --> 00:04:34,320 eighty-four. so if we click on that line, 95 00:04:34,320 --> 00:04:37,090 you get this toolbar, or we can hover 96 00:04:37,090 --> 00:04:39,460 over it first - Variable errorMessage is 97 00:04:39,460 --> 00:04:41,680 assigned but never accessed. Just 98 00:04:41,680 --> 00:04:43,710 come over here and click on the line, 99 00:04:43,710 --> 00:04:46,420 and we want to click on Join declaration 100 00:04:46,420 --> 00:04:49,840 and assignment. So that's a lot nicer and 101 00:04:49,840 --> 00:04:51,190 even more concise than what we had it, 102 00:04:51,190 --> 00:04:53,020 and I think you'd agree that looks a lot 103 00:04:53,020 --> 00:04:56,260 tidier than the previous code. Now using 104 00:04:56,260 --> 00:04:57,880 a block of code as an expression, as 105 00:04:57,880 --> 00:04:59,650 we're doing for each of those branches 106 00:04:59,650 --> 00:05:02,380 in the when, causes the last statement in 107 00:05:02,380 --> 00:05:04,570 the block to be used. Now we've made sure 108 00:05:04,570 --> 00:05:06,580 that the last expression in each branch 109 00:05:06,580 --> 00:05:09,190 is the string that we want to display in 110 00:05:09,190 --> 00:05:11,380 the log. Now that's only relevant for the 111 00:05:11,380 --> 00:05:13,450 security exception, because that's the 112 00:05:13,450 --> 00:05:14,950 only branch that's got more than one 113 00:05:14,950 --> 00:05:17,380 statement, but that's why we had to call 114 00:05:17,380 --> 00:05:19,720 printStackTrace before creating the 115 00:05:19,720 --> 00:05:22,720 string. Now the same warning about the 116 00:05:22,720 --> 00:05:24,520 order of the exception still holds here. 117 00:05:24,520 --> 00:05:26,860 We have to list MalformedURL 118 00:05:26,860 --> 00:05:29,200 Exception before IO exception, for 119 00:05:29,200 --> 00:05:31,060 example, because MalformedURL 120 00:05:31,060 --> 00:05:33,190 Exception is a subclass of IO 121 00:05:33,190 --> 00:05:35,800 Exception. Okay, so we can also improve 122 00:05:35,800 --> 00:05:38,440 the way we read from the inputStream. 123 00:05:38,440 --> 00:05:41,260 Now Android Studio won't help with that, 124 00:05:41,260 --> 00:05:43,090 and the Kotlin code that we'll use is 125 00:05:43,090 --> 00:05:44,620 very different to what we've got here 126 00:05:44,620 --> 00:05:45,510 currently. 127 00:05:45,510 --> 00:05:48,550 Alright, so let's just look at the input 128 00:05:48,550 --> 00:05:51,820 Stream code. So we come up here and have 129 00:05:51,820 --> 00:05:54,250 a look at it. Now Android Studio won't 130 00:05:54,250 --> 00:05:56,140 help with that, and the Kotlin code that 131 00:05:56,140 --> 00:05:57,610 we use is very different to what we've 132 00:05:57,610 --> 00:05:59,770 currently got here. What I'm going to do 133 00:05:59,770 --> 00:06:01,360 is start by deleting the code that we 134 00:06:01,360 --> 00:06:03,790 commented out in an earlier video - these 135 00:06:03,790 --> 00:06:05,170 three lines that we replace with a 136 00:06:05,170 --> 00:06:06,400 single line. Let's just get rid of those 137 00:06:06,400 --> 00:06:10,330 to free up a bit of space here. Now I'm 138 00:06:10,330 --> 00:06:11,950 going to comment out all the code that 139 00:06:11,950 --> 00:06:14,110 we're going to replace, just so you can 140 00:06:14,110 --> 00:06:17,110 compare it to the new code. So we've got 141 00:06:17,110 --> 00:06:18,430 this val reader - we're going to start 142 00:06:18,430 --> 00:06:20,860 on that line. I'm going to move right on 143 00:06:20,860 --> 00:06:23,620 down now to, and including, the reader dot 144 00:06:23,620 --> 00:06:27,390 close, and we'll comment that out, and 145 00:06:27,390 --> 00:06:29,830 instead, what I'm going to do is add the 146 00:06:29,830 --> 00:06:31,780 replacement code, and I'm going to add 147 00:06:31,780 --> 00:06:35,410 the replaceable code below it. So the 148 00:06:35,410 --> 00:06:36,640 replacement code is going to be val 149 00:06:36,640 --> 00:06:41,880 stream equals connection.inputStream. 150 00:06:41,880 --> 00:06:45,520 Then I'm gonna type stream dot 151 00:06:45,520 --> 00:06:50,800 buffered.reader, parentheses there, dot 152 00:06:50,800 --> 00:06:56,349 use, open a code block, and then I'm going 153 00:06:56,349 --> 00:06:58,930 to type in the code block, reader arrow 154 00:06:58,930 --> 00:07:02,590 token, or arrow. On the next line, xml 155 00:07:02,590 --> 00:07:11,430 Resul.append reader.readText. 156 00:07:11,430 --> 00:07:16,210 Then we've got our closing right curly 157 00:07:16,210 --> 00:07:19,270 brace. Now that's definitely more concise 158 00:07:19,270 --> 00:07:21,099 than the code above it and demonstrates 159 00:07:21,099 --> 00:07:22,750 the different approach that functional 160 00:07:22,750 --> 00:07:25,120 programming takes. So instead of 161 00:07:25,120 --> 00:07:26,710 concerning ourselves with the exact 162 00:07:26,710 --> 00:07:28,690 details of how to read from the stream; 163 00:07:28,690 --> 00:07:31,030 using a while loop, counting the characters 164 00:07:31,030 --> 00:07:32,889 received, looping until there's no more 165 00:07:32,889 --> 00:07:35,470 data, and so on, we focus on what we want 166 00:07:35,470 --> 00:07:38,650 to do. So the functional style let's us 167 00:07:38,650 --> 00:07:40,389 specify what we want to do, which in this 168 00:07:40,389 --> 00:07:44,050 case is, take our stream, buffer it, get a 169 00:07:44,050 --> 00:07:46,750 reader and use it to read text and 170 00:07:46,750 --> 00:07:48,639 append the results to our StringBuilder, 171 00:07:48,639 --> 00:07:51,520 which is xmlResult. Now I'm going to 172 00:07:51,520 --> 00:07:52,960 be using the functional programming 173 00:07:52,960 --> 00:07:54,639 style a lot throughout the course, 174 00:07:54,639 --> 00:07:57,909 because the code's a lot cleaner. Now 175 00:07:57,909 --> 00:07:59,530 comparing that code to the code I 176 00:07:59,530 --> 00:08:01,750 commented out, and it's easy to see that 177 00:08:01,750 --> 00:08:03,610 there's far less scope to introduce 178 00:08:03,610 --> 00:08:05,560 errors. We don't have to think about 179 00:08:05,560 --> 00:08:06,849 whether we should be checking for 180 00:08:06,849 --> 00:08:08,979 characters, for charsRead greater than 0, 181 00:08:08,979 --> 00:08:11,320 or charsRead greater than or equal to 182 00:08:11,320 --> 00:08:13,599 zero, for example. It's getting details 183 00:08:13,599 --> 00:08:15,340 like that wrong that can cause subtle 184 00:08:15,340 --> 00:08:18,400 bugs in our code. Now if you're not used 185 00:08:18,400 --> 00:08:20,409 to functional programming, it can take 186 00:08:20,409 --> 00:08:21,340 some getting used to. 187 00:08:21,340 --> 00:08:23,590 Let's just take a moment to see how we 188 00:08:23,590 --> 00:08:25,900 can tell what's going on here. So we're 189 00:08:25,900 --> 00:08:27,520 starting off with an inputStream which 190 00:08:27,520 --> 00:08:29,469 we're getting from our connection - it's 191 00:08:29,469 --> 00:08:31,840 connection.inputStream. That bit's 192 00:08:31,840 --> 00:08:33,789 unchanged, although, we don't really need 193 00:08:33,789 --> 00:08:35,559 to store it in a separate variable. I 194 00:08:35,559 --> 00:08:37,479 just did that so the change is a bit 195 00:08:37,479 --> 00:08:39,578 less drastic. Now we can actually get rid 196 00:08:39,578 --> 00:08:42,039 of stream and do this instead. So I'm 197 00:08:42,039 --> 00:08:44,649 going to delete that first line. I'll 198 00:08:44,649 --> 00:08:46,450 comment out that first line. I'm going to 199 00:08:46,450 --> 00:08:52,420 replace stream with connection.input 200 00:08:52,420 --> 00:08:55,690 Stream. That's even more concise, as you 201 00:08:55,690 --> 00:08:58,329 can see, and to see what buffer is doing, 202 00:08:58,329 --> 00:08:59,139 we can control click on it 203 00:08:59,139 --> 00:09:01,660 to see the Kotlin source. Come over here 204 00:09:01,660 --> 00:09:02,579 and click on it, 205 00:09:02,579 --> 00:09:05,879 remembering it's command on a Mac. Now 206 00:09:05,879 --> 00:09:08,319 the comments here are normally 207 00:09:08,319 --> 00:09:09,850 sufficient, rather than trying to 208 00:09:09,850 --> 00:09:12,040 understand the code, but here we can see 209 00:09:12,040 --> 00:09:13,959 that it creates a BufferedInputStream, 210 00:09:13,959 --> 00:09:16,569 wrapping this stream, which is exactly 211 00:09:16,569 --> 00:09:18,549 what we did in the earlier code when we 212 00:09:18,549 --> 00:09:21,309 used the BufferedReader. Now below that, by 213 00:09:21,309 --> 00:09:24,179 the way, is the InputStream.reader 214 00:09:24,179 --> 00:09:26,169 function, so there's no need to go back 215 00:09:26,169 --> 00:09:27,699 to the code to control or command click 216 00:09:27,699 --> 00:09:31,119 on reader. And it creates a reader on 217 00:09:31,119 --> 00:09:32,949 this InputStream, again, just what we had 218 00:09:32,949 --> 00:09:35,139 in the previous Object Oriented 219 00:09:35,139 --> 00:09:37,209 Programming code, using the InputStream 220 00:09:37,209 --> 00:09:39,129 Reader. So, so far everything's been 221 00:09:39,129 --> 00:09:41,199 pretty much the same. Where it gets 222 00:09:41,199 --> 00:09:42,549 really interesting, though, going back to 223 00:09:42,549 --> 00:09:46,929 our code, is when we use this lambda to 224 00:09:46,929 --> 00:09:48,609 do the reading. So if we come on down 225 00:09:48,609 --> 00:09:53,739 here and we want to control click use, and 226 00:09:53,739 --> 00:09:55,569 we can see that it executes the given 227 00:09:55,569 --> 00:09:58,179 block - that's our lambda on this resource - 228 00:09:58,179 --> 00:10:01,600 and then closes it down correctly. Now 229 00:10:01,600 --> 00:10:03,399 that removes the need to call reader dot 230 00:10:03,399 --> 00:10:05,739 close, and it'll deal correctly with any 231 00:10:05,739 --> 00:10:08,169 exceptions that have thrown. Now the 232 00:10:08,169 --> 00:10:10,089 function code itself may look a bit 233 00:10:10,089 --> 00:10:12,160 complex but don't worry about that. 234 00:10:12,160 --> 00:10:14,799 When using the Kotlin or Java libraries, 235 00:10:14,799 --> 00:10:17,049 we're interested in what things do, not 236 00:10:17,049 --> 00:10:19,449 in exactly how they work. We're learning 237 00:10:19,449 --> 00:10:21,100 how to write apps, not learning how to 238 00:10:21,100 --> 00:10:23,350 write the Android framework. Now the 239 00:10:23,350 --> 00:10:25,089 lambda function uses the reader 240 00:10:25,089 --> 00:10:28,239 parameter to read the text and append it 241 00:10:28,239 --> 00:10:30,730 to xmlResult. So it's worth having a 242 00:10:30,730 --> 00:10:32,049 quick look at the readText 243 00:10:32,049 --> 00:10:34,389 function. So if we just close that down 244 00:10:34,389 --> 00:10:40,179 and go back and ctrl-click the readText 245 00:10:40,179 --> 00:10:43,449 function, or command again on a Mac, and 246 00:10:43,449 --> 00:10:45,279 you can see it says it reads this reader 247 00:10:45,279 --> 00:10:47,439 completely as a string. And again, that's 248 00:10:47,439 --> 00:10:47,860 good - 249 00:10:47,860 --> 00:10:50,319 that's exactly what we wanted it to do. 250 00:10:50,319 --> 00:10:52,569 What's interesting, though, is how it does 251 00:10:52,569 --> 00:10:55,449 it. It uses copyTo and the source for 252 00:10:55,449 --> 00:10:58,119 copyTo appears just below. Now if we just 253 00:10:58,119 --> 00:10:59,309 scroll down and have a bit of a look there, 254 00:10:59,309 --> 00:11:02,189 if that looks familiar, then it should. 255 00:11:02,189 --> 00:11:04,539 Now I haven't done this in a video 256 00:11:04,539 --> 00:11:06,579 before but in theory it should work. So 257 00:11:06,579 --> 00:11:08,410 I'm going to drag the tab for the 258 00:11:08,410 --> 00:11:11,949 ReadWrite.kt file out of Android 259 00:11:11,949 --> 00:11:13,030 Studio so it appears in it's own 260 00:11:13,030 --> 00:11:15,220 window. And to do that, I just need to 261 00:11:15,220 --> 00:11:17,200 make this window a little bit smaller, so 262 00:11:17,200 --> 00:11:19,210 I'm gonna go ahead and do that. So I'm 263 00:11:19,210 --> 00:11:22,870 gonna drag that out, and then I'm going 264 00:11:22,870 --> 00:11:27,670 to go back and expand this again, and 265 00:11:27,670 --> 00:11:30,070 we've got this other window now. So what 266 00:11:30,070 --> 00:11:32,560 I'm going to do then, is I'm going to go 267 00:11:32,560 --> 00:11:34,600 back to our MainActivity. I'm going to 268 00:11:34,600 --> 00:11:35,890 close down the project pane to make a 269 00:11:35,890 --> 00:11:37,420 bit of space. Then I'm going to bring this 270 00:11:37,420 --> 00:11:39,730 back again and just make it a little bit 271 00:11:39,730 --> 00:11:42,910 smaller, so that it actually fits a 272 00:11:42,910 --> 00:11:45,520 little bit better, and we can compare 273 00:11:45,520 --> 00:11:50,200 this code now, on the right hand side, to 274 00:11:50,200 --> 00:11:52,840 the code that we've got commented out. So 275 00:11:52,840 --> 00:11:54,370 we're, basically, comparing the two sets 276 00:11:54,370 --> 00:11:56,980 of code. Now the variable names are 277 00:11:56,980 --> 00:11:59,140 different but you can see that both bits 278 00:11:59,140 --> 00:12:01,390 of code use a CharArray as a buffer, and 279 00:12:01,390 --> 00:12:04,150 use a while loop to keep reading until 280 00:12:04,150 --> 00:12:06,460 the number of chars read is less than 281 00:12:06,460 --> 00:12:09,370 zero. So, ultimately, our functional code 282 00:12:09,370 --> 00:12:11,560 is doing the same thing as our previous 283 00:12:11,560 --> 00:12:14,170 code. Now one advantage of using 284 00:12:14,170 --> 00:12:16,180 functional programming is that this 285 00:12:16,180 --> 00:12:18,880 library code, in ReadWrite.kt, has 286 00:12:18,880 --> 00:12:20,680 probably already been used in thousands 287 00:12:20,680 --> 00:12:23,080 of programs. The more people that use 288 00:12:23,080 --> 00:12:24,460 Kotlin, the more these libraries get 289 00:12:24,460 --> 00:12:27,160 tested and any bugs get ironed out. Now 290 00:12:27,160 --> 00:12:28,960 the while loop that we had earlier would 291 00:12:28,960 --> 00:12:30,700 need to be tested, and if there was a 292 00:12:30,700 --> 00:12:32,560 subtle bug, there's far less chance that 293 00:12:32,560 --> 00:12:35,350 we'd spot it. So as well as cleaner code, 294 00:12:35,350 --> 00:12:37,360 we also get the benefit of all that 295 00:12:37,360 --> 00:12:39,730 extra testing that the standard 296 00:12:39,730 --> 00:12:41,710 libraries are subjected to. So I think 297 00:12:41,710 --> 00:12:43,060 that makes a good case for using 298 00:12:43,060 --> 00:12:44,560 functional programming wherever possible, 299 00:12:44,560 --> 00:12:46,480 so that's what I'm going to be doing it 300 00:12:46,480 --> 00:12:48,370 throughout the course. Alright, so I'm going 301 00:12:48,370 --> 00:12:50,830 to close down this window now. There's 302 00:12:50,830 --> 00:12:52,150 one more change we're going to make to 303 00:12:52,150 --> 00:12:55,120 our lambda. Now if you've taken Sara 304 00:12:55,120 --> 00:12:57,130 Etrich's Kotlin for Java developers course, 305 00:12:57,130 --> 00:12:58,780 which is a course from the learn 306 00:12:58,780 --> 00:13:00,790 programming academy as well, you'll know 307 00:13:00,790 --> 00:13:02,260 that we don't have to use an explicit 308 00:13:02,260 --> 00:13:04,660 parameter here - we can replace reader 309 00:13:04,660 --> 00:13:08,310 with it. I'm getting back to the code, 310 00:13:08,310 --> 00:13:12,190 again, here on line 65. So again, for that 311 00:13:12,190 --> 00:13:13,870 lambda, we don't really have to use an 312 00:13:13,870 --> 00:13:15,760 explicit parameter - we can replace reader 313 00:13:15,760 --> 00:13:18,640 with it. And Android Studio actually 314 00:13:18,640 --> 00:13:20,650 suggests that, in fact. If I click on 315 00:13:20,650 --> 00:13:24,040 reader, we'll get a suggestion over here. 316 00:13:24,040 --> 00:13:25,720 I come over here and click on the 317 00:13:25,720 --> 00:13:26,920 light bulb. 318 00:13:26,920 --> 00:13:29,410 We can replace explicit parameter reader 319 00:13:29,410 --> 00:13:31,629 with it. So I'm going to do that by 320 00:13:31,629 --> 00:13:34,899 clicking on it, and I can just put that back 321 00:13:34,899 --> 00:13:39,939 so it's all on the same line now - just 322 00:13:39,939 --> 00:13:41,290 removing the whitespace and we can 323 00:13:41,290 --> 00:13:43,989 even remove the next line. So with a 324 00:13:43,989 --> 00:13:46,359 single statement like we've got now - and 325 00:13:46,359 --> 00:13:48,249 I've done that because in a single 326 00:13:48,249 --> 00:13:50,350 statement like we've ended up with, it's 327 00:13:50,350 --> 00:13:51,910 usual to put it all on the one line which 328 00:13:51,910 --> 00:13:55,449 is why I've done that. But that one line 329 00:13:55,449 --> 00:13:57,429 of code replaces all the commented out 330 00:13:57,429 --> 00:14:01,389 code above it. I think you'd have to agree 331 00:14:01,389 --> 00:14:03,669 that's pretty impressive - so impressive 332 00:14:03,669 --> 00:14:05,379 that we better run the app again to make 333 00:14:05,379 --> 00:14:07,509 sure it still works. So let's just do 334 00:14:07,509 --> 00:14:08,889 that - make sure that things are still 335 00:14:08,889 --> 00:14:18,879 working. Looking at our logcat, and you 336 00:14:18,879 --> 00:14:20,489 can see that we've still managed to 337 00:14:20,489 --> 00:14:23,079 download the XML, so everything's working 338 00:14:23,079 --> 00:14:27,249 fine. And just confirming that our events 339 00:14:27,249 --> 00:14:28,689 are still being called; we're still 340 00:14:28,689 --> 00:14:30,850 getting the response code of 200, and the 341 00:14:30,850 --> 00:14:33,970 XML, and the amount received, etc. Al 342 00:14:33,970 --> 00:14:35,069 right, so I want to stop this video here. 343 00:14:35,069 --> 00:14:37,299 The next video is going to be a very 344 00:14:37,299 --> 00:14:39,369 short one, just like the code we're going 345 00:14:39,369 --> 00:14:41,919 to produce. I'm starting a new video so 346 00:14:41,919 --> 00:14:43,299 that this code's available with the 347 00:14:43,299 --> 00:14:45,339 resources for this one. Now there's a 348 00:14:45,339 --> 00:14:47,259 reason for that, and the reason is I'm 349 00:14:47,259 --> 00:14:48,939 going to delete all the code in this 350 00:14:48,939 --> 00:14:51,220 method and replace it with a single line. 351 00:14:51,220 --> 00:14:53,649 That's right - the 27 lines of code we've 352 00:14:53,649 --> 00:14:55,809 got here can be replaced with just one 353 00:14:55,809 --> 00:14:58,119 line in Kotlin. So let's work on that in 354 00:14:58,119 --> 00:15:00,899 the next video.