1 00:00:04,720 --> 00:00:07,180 Alright, so in MainActivity, we need to 2 00:00:07,180 --> 00:00:09,370 add the code to use the menu that we 3 00:00:09,370 --> 00:00:12,130 created in the previous video. Now if you 4 00:00:12,130 --> 00:00:14,320 chose the Basic Activity template when 5 00:00:14,320 --> 00:00:16,209 creating this project, then you'll 6 00:00:16,209 --> 00:00:18,070 already have a stub for the two methods 7 00:00:18,070 --> 00:00:20,260 we need, but so we can get Android Studio 8 00:00:20,260 --> 00:00:22,630 to generate them for us anyway. So what 9 00:00:22,630 --> 00:00:24,460 I'm going to do is, I'm going to go back 10 00:00:24,460 --> 00:00:27,010 to our MainActivity, and I'm going to 11 00:00:27,010 --> 00:00:29,620 put the cursor after the 12 00:00:29,620 --> 00:00:33,219 onCreate method, down here, and then I'm 13 00:00:33,219 --> 00:00:37,120 going to do a Ctrl-O, and the methods 14 00:00:37,120 --> 00:00:38,800 that we want here are the onCreate 15 00:00:38,800 --> 00:00:41,739 )ptionsMenu, and also the onOptions 16 00:00:41,739 --> 00:00:43,690 Items Selected. So here, the search 17 00:00:43,690 --> 00:00:45,339 feature in this dialogue is really helpful, 18 00:00:45,339 --> 00:00:51,399 so if I type onoptionsmenu, it finds 19 00:00:51,399 --> 00:00:53,260 matches even if this actually 20 00:00:53,260 --> 00:00:55,210 represents two different words. Now there's a 21 00:00:55,210 --> 00:00:57,309 few actual entries with onOptionsMenu 22 00:00:57,309 --> 00:00:59,139 in their names, and the highlighting 23 00:00:59,139 --> 00:01:00,609 makes it very easy to spot the ones we 24 00:01:00,609 --> 00:01:03,039 want. So I'm just gonna press the down 25 00:01:03,039 --> 00:01:04,809 arrow until we get to the one we want - 26 00:01:04,809 --> 00:01:06,310 we've got onCreateOptionsMenu, on 27 00:01:06,310 --> 00:01:09,700 OptionsMenu, onPrepareOptionsMenu. So 28 00:01:09,700 --> 00:01:11,080 onCreateOptionsMenu is the one we 29 00:01:11,080 --> 00:01:13,090 want, then the other one we want is on 30 00:01:13,090 --> 00:01:16,549 OptionsItemSelected - 31 00:01:16,549 --> 00:01:18,329 that's this one here. So I'm actually 32 00:01:18,329 --> 00:01:20,909 going to command click that on a Mac, 33 00:01:20,909 --> 00:01:22,619 and I've now got that one selected, and I've 34 00:01:22,619 --> 00:01:23,909 also got the other one selected. You do a 35 00:01:23,909 --> 00:01:26,189 Ctrl click if you're on Windows or Linux, 36 00:01:26,189 --> 00:01:28,520 click on OK, and we've got our two 37 00:01:28,520 --> 00:01:31,109 functions now created, or overridden for 38 00:01:31,109 --> 00:01:35,219 us. Now onCreateOptionsMenu - that 39 00:01:35,219 --> 00:01:36,689 function's called when it's time to 40 00:01:36,689 --> 00:01:39,119 inflate the activities menu, and that 41 00:01:39,119 --> 00:01:41,609 means that, which means create the menu 42 00:01:41,609 --> 00:01:44,069 objects from the XML file. Now we've got 43 00:01:44,069 --> 00:01:45,869 this basic stub now, so I need to change 44 00:01:45,869 --> 00:01:48,569 it slightly. Now when we try to inflate a 45 00:01:48,569 --> 00:01:50,700 view in the adapter, we have to get an 46 00:01:50,700 --> 00:01:53,039 inflator from the context. But an 47 00:01:53,039 --> 00:01:55,140 Activity or appCompatActivity is a 48 00:01:55,140 --> 00:01:58,409 context, so we can just call getMenu 49 00:01:58,409 --> 00:01:58,979 Inflator 50 00:01:58,979 --> 00:02:01,500 to get an inflater directly, then call its 51 00:02:01,500 --> 00:02:03,599 inflate method and give it the resource 52 00:02:03,599 --> 00:02:07,170 ID of the xml file, containing the menu's 53 00:02:07,170 --> 00:02:09,299 xml. So let's have a look at doing that. 54 00:02:09,299 --> 00:02:11,519 So this is in the onCreateOptionsMenu, 55 00:02:11,519 --> 00:02:14,040 and what I'm going to do here is remove 56 00:02:14,040 --> 00:02:17,459 the super call. So the call's going to 57 00:02:17,459 --> 00:02:23,040 be menuInflator.inflate, and then 58 00:02:23,040 --> 00:02:27,269 parentheses, R.menu. and it's going 59 00:02:27,269 --> 00:02:30,389 to be feeds_menu comma space and 60 00:02:30,389 --> 00:02:31,980 I'm just gonna type menu as the second 61 00:02:31,980 --> 00:02:33,930 argument. Then we're going to return 62 00:02:33,930 --> 00:02:38,340 true. Now as this is Kotlin, we don't have 63 00:02:38,340 --> 00:02:39,959 to use the getters and setters, when 64 00:02:39,959 --> 00:02:41,639 calling the Java code in the Android 65 00:02:41,639 --> 00:02:43,739 Framework. We can refer to the menu 66 00:02:43,739 --> 00:02:46,109 Inflator property directly and use its, 67 00:02:46,109 --> 00:02:48,690 or call rather, it's inflate method. We 68 00:02:48,690 --> 00:02:50,400 then have to return true to tell Android 69 00:02:50,400 --> 00:02:52,680 that we have inflated a menu, and let's 70 00:02:52,680 --> 00:02:54,680 just try this. We're going to run the app 71 00:02:54,680 --> 00:02:57,599 in the emulator, and just confirm that we 72 00:02:57,599 --> 00:03:02,310 can actually see the menu. 73 00:03:02,310 --> 00:03:04,450 Okay, and if we come over here now and 74 00:03:04,450 --> 00:03:06,040 click on the little three buttons, 75 00:03:06,040 --> 00:03:07,990 we can see our menu is actually showing 76 00:03:07,990 --> 00:03:10,210 up there now. So that's good - we've got a 77 00:03:10,210 --> 00:03:14,110 menu in our application. Alright, so back 78 00:03:14,110 --> 00:03:16,750 to the code. So creating and displaying the 79 00:03:16,750 --> 00:03:19,090 menu is really very easy. Now the menu 80 00:03:19,090 --> 00:03:20,620 doesn't do anything yet - we have to write 81 00:03:20,620 --> 00:03:22,450 some code to, you know, specify what 82 00:03:22,450 --> 00:03:24,100 happens when the various items are 83 00:03:24,100 --> 00:03:26,500 selected, but we're well on the way. Now 84 00:03:26,500 --> 00:03:27,910 you've probably guessed that the place 85 00:03:27,910 --> 00:03:30,430 to specify what the menu items do, is 86 00:03:30,430 --> 00:03:33,340 that onSelected, onOptions rather, Items 87 00:03:33,340 --> 00:03:35,710 Selected function. Now it's called 88 00:03:35,710 --> 00:03:37,600 whenever an item's selected from the 89 00:03:37,600 --> 00:03:40,060 options menu. Now as different options 90 00:03:40,060 --> 00:03:41,440 are selected, we're going to be changing 91 00:03:41,440 --> 00:03:44,080 the url that's used to access the feed. 92 00:03:44,080 --> 00:03:46,060 So we need to store the url in a 93 00:03:46,060 --> 00:03:47,500 variable. So let's have a look at doing 94 00:03:47,500 --> 00:03:50,080 that. So again, what I'm going to do is remove 95 00:03:50,080 --> 00:03:52,510 the return call. We're gonna start on 96 00:03:52,510 --> 00:03:59,560 this with val feedUrl colon String. Then 97 00:03:59,560 --> 00:04:01,890 I'm gonna type, on the next line, when 98 00:04:01,890 --> 00:04:06,730 parenthesis item.itemId, right 99 00:04:06,730 --> 00:04:10,120 parenthesis and open a code block. But, as 100 00:04:10,120 --> 00:04:11,290 you can see, we're actually getting an 101 00:04:11,290 --> 00:04:13,510 error here. So Kotlin's objecting 102 00:04:13,510 --> 00:04:15,790 because we're accessing a property of a 103 00:04:15,790 --> 00:04:19,180 nullable type. Now item's passed in as a 104 00:04:19,180 --> 00:04:21,459 MenuItem? type, so it can 105 00:04:21,459 --> 00:04:23,500 be null. Now once again, it wouldn't 106 00:04:23,500 --> 00:04:25,840 surprise me if Google and an @NonNull 107 00:04:25,840 --> 00:04:28,300 annotation to that, so you may well not 108 00:04:28,300 --> 00:04:29,890 be getting this error, depending on when 109 00:04:29,890 --> 00:04:31,840 you're watching this. At the moment 110 00:04:31,840 --> 00:04:33,730 though, we can either use the safe call 111 00:04:33,730 --> 00:04:36,250 operator when accessing itemId, or we 112 00:04:36,250 --> 00:04:39,070 can modify the function signature. Now, I 113 00:04:39,070 --> 00:04:41,200 previously said that modifying these 114 00:04:41,200 --> 00:04:42,670 function signatures isn't something 115 00:04:42,670 --> 00:04:44,260 you should do without a lot of thought, 116 00:04:44,260 --> 00:04:46,390 so now I'm suggesting we do it for a 117 00:04:46,390 --> 00:04:48,910 second time. How can you be sure, or how 118 00:04:48,910 --> 00:04:50,350 can we be sure that it's a safe thing to 119 00:04:50,350 --> 00:04:52,990 do here? Now if you go ahead and modify the 120 00:04:52,990 --> 00:04:54,760 function signature so that the item 121 00:04:54,760 --> 00:04:57,070 parameter is of type MenuItem, rather 122 00:04:57,070 --> 00:04:58,750 than the nullable MenuItem? - 123 00:04:58,750 --> 00:05:00,760 that's the one with the question 124 00:05:00,760 --> 00:05:03,670 mark after it, up here - then we need to be 125 00:05:03,670 --> 00:05:05,650 absolutely certain that item can never 126 00:05:05,650 --> 00:05:06,340 be null. 127 00:05:06,340 --> 00:05:08,470 Can we be certain? Well actually, yes we 128 00:05:08,470 --> 00:05:11,320 can. This onOptionsItemSelected 129 00:05:11,320 --> 00:05:13,840 function's called, when a user selects an 130 00:05:13,840 --> 00:05:15,670 item from the menu. Now if 131 00:05:15,670 --> 00:05:17,500 they've selected the item, then there must 132 00:05:17,500 --> 00:05:19,600 be an item, otherwise, they couldn't have 133 00:05:19,600 --> 00:05:21,970 selected it in the first place. But with 134 00:05:21,970 --> 00:05:24,040 that said, I'll say it again, don't go 135 00:05:24,040 --> 00:05:25,420 changing these override function 136 00:05:25,420 --> 00:05:26,920 signatures without a full understanding 137 00:05:26,920 --> 00:05:29,950 of what's happening behind the scenes. If 138 00:05:29,950 --> 00:05:31,330 you're not sure, then the best thing to 139 00:05:31,330 --> 00:05:33,420 do is call the safe call operator. 140 00:05:33,420 --> 00:05:35,410 Alright, so I'm going to come back and 141 00:05:35,410 --> 00:05:37,090 do that - I'm going to put the question 142 00:05:37,090 --> 00:05:38,920 mark after the item, down here in the 143 00:05:38,920 --> 00:05:42,160 when call, and that actually removes the 144 00:05:42,160 --> 00:05:44,200 error. Basically, Kotlin is going to 145 00:05:44,200 --> 00:05:46,360 ignore this when expression if item is 146 00:05:46,360 --> 00:05:49,180 null, and that's perfectly acceptable. So 147 00:05:49,180 --> 00:05:50,830 if you're working with other framework 148 00:05:50,830 --> 00:05:52,990 functions, use the safe call operator on 149 00:05:52,990 --> 00:05:55,090 nullable types. Alright, now I'm going 150 00:05:55,090 --> 00:05:57,070 to modify the signature here, though, so 151 00:05:57,070 --> 00:05:58,330 I'm going to undo that change, but I'm 152 00:05:58,330 --> 00:05:59,890 just, sort of, showing you there was an 153 00:05:59,890 --> 00:06:01,180 alternative to this. So I'm going to undo 154 00:06:01,180 --> 00:06:03,130 that change, and instead, what we're going 155 00:06:03,130 --> 00:06:05,080 to do is remove the question mark from 156 00:06:05,080 --> 00:06:08,560 the menu, or from the parameters that was 157 00:06:08,560 --> 00:06:10,540 passed to this method - we talked about 158 00:06:10,540 --> 00:06:13,090 the reason why that's valid. Al 159 00:06:13,090 --> 00:06:15,220 right, so that's fixed the error, and we can 160 00:06:15,220 --> 00:06:17,470 now add the branches to the when. Now 161 00:06:17,470 --> 00:06:18,550 let's go ahead and do that, so we're 162 00:06:18,550 --> 00:06:20,170 going to go through each menu option and 163 00:06:20,170 --> 00:06:24,370 what to do. So I'm gonna start here, so 164 00:06:24,370 --> 00:06:27,370 within the when clause itself, when, it's gonna 165 00:06:27,370 --> 00:06:30,430 be R.id. and we're gonna do menu 166 00:06:30,430 --> 00:06:34,300 Free first, then add our arrow token. Then the 167 00:06:34,300 --> 00:06:39,120 next line, I'm gonna put feedURL is equal to. 168 00:06:39,120 --> 00:06:42,850 Now I'm just gonna copy this link, okay, and 169 00:06:42,850 --> 00:06:47,250 I'm going to paste it in there, like so. 170 00:06:47,250 --> 00:06:50,110 So that's the Top 10 Free applications. 171 00:06:50,110 --> 00:06:53,740 The next one's gonna be R.id. 172 00:06:53,740 --> 00:06:58,710 mnuPaid, arrow token again, feedUrl 173 00:06:58,710 --> 00:07:01,420 equals, and you can get these links from 174 00:07:01,420 --> 00:07:03,720 either the RSS feeds folder. 175 00:07:03,720 --> 00:07:05,470 Alternatively, what you can do is just, 176 00:07:05,470 --> 00:07:07,300 we'll have a link or have them accessible, 177 00:07:07,300 --> 00:07:09,430 as in a text file in the resources 178 00:07:09,430 --> 00:07:11,290 section for this video, and you can do 179 00:07:11,290 --> 00:07:12,160 the same thing there. 180 00:07:12,160 --> 00:07:13,680 I'll just fix up that error there. 181 00:07:13,680 --> 00:07:16,210 Alright, so that's for the Top 10 Paid 182 00:07:16,210 --> 00:07:20,220 applications, and for the last one, R.id. 183 00:07:20,220 --> 00:07:23,710 mnuSongs, arrow token, and it's going to 184 00:07:23,710 --> 00:07:28,990 be feedURL equals. And for that one, I'm 185 00:07:28,990 --> 00:07:29,560 going to grab 186 00:07:29,560 --> 00:07:33,190 the top songs - RSS feed link - and 187 00:07:33,190 --> 00:07:36,550 paste that in. So that's three options. 188 00:07:36,550 --> 00:07:38,410 We're going to add an else, arrow token and 189 00:07:38,410 --> 00:07:43,510 it's going to be returned super.on 190 00:07:43,510 --> 00:07:49,230 OptionsItemSelected item, and then 191 00:07:49,230 --> 00:07:53,260 we're going to delete this line, and 192 00:07:53,260 --> 00:07:56,260 outside of the when, we're going to do a 193 00:07:56,260 --> 00:08:00,639 return super.onOptionsItemSelected 194 00:08:00,639 --> 00:08:02,160 per item. 195 00:08:02,160 --> 00:08:05,290 Now again, with the urls, I copied 196 00:08:05,290 --> 00:08:06,850 them off-screen, but you could just go to 197 00:08:06,850 --> 00:08:08,560 the Apple's website and paste them in - the 198 00:08:08,560 --> 00:08:09,850 RSS feeds that we've looked at 199 00:08:09,850 --> 00:08:11,800 previously - or there's going to be a text 200 00:08:11,800 --> 00:08:14,440 file in this video video's resources 201 00:08:14,440 --> 00:08:15,790 section and you can just grab them from 202 00:08:15,790 --> 00:08:18,310 there. So now that we've done this, when a 203 00:08:18,310 --> 00:08:21,430 menu item's selected, feedURL will hold 204 00:08:21,430 --> 00:08:23,080 the address of the corresponding RSS 205 00:08:23,080 --> 00:08:25,690 feed. So we can then pass that url to a 206 00:08:25,690 --> 00:08:27,520 downloadUrl function to download the 207 00:08:27,520 --> 00:08:29,380 data. I'm going to write that in a moment, 208 00:08:29,380 --> 00:08:32,020 but first, let's just finish off the on 209 00:08:32,020 --> 00:08:35,679 OptionsItemSelected function. So in 210 00:08:35,679 --> 00:08:36,700 fact, what we'll do here is we'll get 211 00:08:36,700 --> 00:08:39,460 rid of this return, and we're going to 212 00:08:39,460 --> 00:08:42,599 change it to downloadUrl 213 00:08:42,599 --> 00:08:47,589 parentheses feedUrl, and then we're 214 00:08:47,589 --> 00:08:49,320 going to return true. 215 00:08:49,320 --> 00:08:53,320 Now this else branch is very important, 216 00:08:53,320 --> 00:08:55,180 and you should always include it when 217 00:08:55,180 --> 00:08:57,210 creating code to react to menu choices. 218 00:08:57,210 --> 00:08:59,350 Now at the moment, it should never 219 00:08:59,350 --> 00:09:02,290 execute, and that's because, on the three 220 00:09:02,290 --> 00:09:04,270 lines above, we've matched every one of 221 00:09:04,270 --> 00:09:06,010 the, or each of the possible entries in 222 00:09:06,010 --> 00:09:08,350 our menu. But it's possible to create 223 00:09:08,350 --> 00:09:10,510 sub-menus, though, and we're actually going to be 224 00:09:10,510 --> 00:09:12,880 doing that soon. Now when you go into one 225 00:09:12,880 --> 00:09:14,890 of those sub-menus, Android triggers a 226 00:09:14,890 --> 00:09:16,839 call to this method when the sub-menu's 227 00:09:16,839 --> 00:09:19,089 opened. If you don't return from the else 228 00:09:19,089 --> 00:09:21,610 branch, then any code after the when will 229 00:09:21,610 --> 00:09:23,770 execute, which could cause problems. And 230 00:09:23,770 --> 00:09:25,510 here, in fact, it would call the download 231 00:09:25,510 --> 00:09:27,400 URL method with an empty string, 232 00:09:27,400 --> 00:09:30,339 which isn't very good - which isn't good 233 00:09:30,339 --> 00:09:31,690 at all. So you definitely want to check for 234 00:09:31,690 --> 00:09:33,670 that - have that else branch present. 235 00:09:33,670 --> 00:09:36,070 Alright, so what's this downloadURL 236 00:09:36,070 --> 00:09:38,620 function for? Well what we're going to do, 237 00:09:38,620 --> 00:09:41,470 is once the URL has changed, is exactly 238 00:09:41,470 --> 00:09:42,579 what we currently do in the 239 00:09:42,579 --> 00:09:44,559 onCreate method. We're going to create a 240 00:09:44,559 --> 00:09:46,749 new DownloadData object. We're going to 241 00:09:46,749 --> 00:09:48,819 call its execute method with the new URL, 242 00:09:48,819 --> 00:09:51,519 and because duplicating code is a bad 243 00:09:51,519 --> 00:09:53,649 idea, I'm actually going to move those 244 00:09:53,649 --> 00:09:55,600 few lines into their own method and call 245 00:09:55,600 --> 00:09:58,149 that method in onCreate, and also here in 246 00:09:58,149 --> 00:10:01,299 the onOptionsItemSelected. So let's have 247 00:10:01,299 --> 00:10:03,549 a go at doing that now. So I'm going to 248 00:10:03,549 --> 00:10:06,220 actually put this above the, we'll actually put 249 00:10:06,220 --> 00:10:09,910 it just below the onCreate menu, and it's 250 00:10:09,910 --> 00:10:15,329 going to be private fun downloadURL 251 00:10:15,329 --> 00:10:18,670 parenthesis. It's gonna be feedURL : 252 00:10:18,670 --> 00:10:23,199 as a String. Alright, so what we're going 253 00:10:23,199 --> 00:10:25,689 to do then, is actually move these three 254 00:10:25,689 --> 00:10:28,170 lines here, out of the onCreate method. 255 00:10:28,170 --> 00:10:32,619 We're gonna cut those out. Okay, so move them out 256 00:10:32,619 --> 00:10:35,980 of there, and paste them into the 257 00:10:35,980 --> 00:10:38,110 downloadUrl method. Let's change the 258 00:10:38,110 --> 00:10:41,709 text here, or the message, and we'll go 259 00:10:41,709 --> 00:10:48,119 with downloadUrl starting AsyncTask, 260 00:10:48,119 --> 00:10:53,709 and instead of onCreate done, let's go 261 00:10:53,709 --> 00:10:59,079 with downloadUrl done. And now that 262 00:10:59,079 --> 00:11:00,489 obvious change is to change the 263 00:11:00,489 --> 00:11:04,569 hard-coded parameter here, for execute. I'm 264 00:11:04,569 --> 00:11:06,160 going to delete that, and that should now 265 00:11:06,160 --> 00:11:11,499 be feedUrl. What I'll do is, before that, 266 00:11:11,499 --> 00:11:15,669 I'll undo that change, because I need 267 00:11:15,669 --> 00:11:20,649 that string - you'll see why shortly. Then 268 00:11:20,649 --> 00:11:22,149 I'll just go back and delete it again and 269 00:11:22,149 --> 00:11:26,559 put feedUrl in there. Then back in 270 00:11:26,559 --> 00:11:28,869 here, in our onCreate, we still 271 00:11:28,869 --> 00:11:30,069 want to call this function. So what I'm 272 00:11:30,069 --> 00:11:32,819 going to do is do a downloadUrl 273 00:11:32,819 --> 00:11:35,769 parenthesis, and I'm going to paste that 274 00:11:35,769 --> 00:11:39,519 in there, like so. So we're calling that 275 00:11:39,519 --> 00:11:41,739 method, and I'm going to add a Log.d, so 276 00:11:41,739 --> 00:11:47,390 Log.d TAG onCreate done. 277 00:11:47,390 --> 00:11:50,690 I guess i could've left that in there, 278 00:11:50,690 --> 00:11:53,120 instead of typing it again. Okay, so you 279 00:11:53,120 --> 00:11:53,960 can see what we've done there now. 280 00:11:53,960 --> 00:11:55,670 WE've changed the two logging lines to 281 00:11:55,670 --> 00:11:57,410 log the name of the new method, but 282 00:11:57,410 --> 00:11:58,400 otherwise you can see, it's pretty much 283 00:11:58,400 --> 00:12:00,710 the same code that we had, with the URL 284 00:12:00,710 --> 00:12:03,650 now parameterised. Now if that last bit 285 00:12:03,650 --> 00:12:05,900 looked a little bit too easy, to be true, 286 00:12:05,900 --> 00:12:08,510 well it is. We should now be able to 287 00:12:08,510 --> 00:12:09,920 choose one of the three feeds from the 288 00:12:09,920 --> 00:12:12,980 menu, so I'm going to try and test that 289 00:12:12,980 --> 00:12:18,710 and see that that works - have our app running. 290 00:12:18,710 --> 00:12:20,850 alright, so there's our app running, so 291 00:12:20,850 --> 00:12:23,760 so far, so good - it's working okay. What's 292 00:12:23,760 --> 00:12:25,140 not so good, though, is what happens when 293 00:12:25,140 --> 00:12:27,420 I select one of the menu items. So if I come 294 00:12:27,420 --> 00:12:29,820 up here, and just click on one of 295 00:12:29,820 --> 00:12:31,860 them - Free apps - you can see we've got a 296 00:12:31,860 --> 00:12:32,760 crash, right away, 297 00:12:32,760 --> 00:12:35,520 and the problem is that you can't use an 298 00:12:35,520 --> 00:12:37,110 AsyncTask more than once. 299 00:12:37,110 --> 00:12:40,290 There's no way to restart one. Now you can 300 00:12:40,290 --> 00:12:42,000 create as many instances as you want but 301 00:12:42,000 --> 00:12:44,610 each instance can only be used once. And 302 00:12:44,610 --> 00:12:46,230 just to confirm that, if we go back to 303 00:12:46,230 --> 00:12:51,810 the log cat and have a look, and you can see 304 00:12:51,810 --> 00:12:54,510 the error message there; Cannot execute 305 00:12:54,510 --> 00:12:56,460 task: the task has already been executed 306 00:12:56,460 --> 00:12:58,710 (a task can only be executed once) only 307 00:12:58,710 --> 00:13:01,560 once. So fortunately though, we can fix 308 00:13:01,560 --> 00:13:03,270 this easily by just creating a new 309 00:13:03,270 --> 00:13:05,250 DownloadData instance, each time we want 310 00:13:05,250 --> 00:13:05,970 to run the task. 311 00:13:05,970 --> 00:13:08,820 The only real complication here is that 312 00:13:08,820 --> 00:13:10,760 we need downloadData to be visible 313 00:13:10,760 --> 00:13:13,020 throughout our Activity, so that we can 314 00:13:13,020 --> 00:13:14,640 cancel it if necessary, in the 315 00:13:14,640 --> 00:13:16,740 onDestroy method. What that means is we 316 00:13:16,740 --> 00:13:18,660 can't initialize it when we declare it, 317 00:13:18,660 --> 00:13:23,100 back up here, up here on line 35. Now we 318 00:13:23,100 --> 00:13:25,260 have to set it to null here, because 319 00:13:25,260 --> 00:13:27,030 variables have to be initialized to 320 00:13:27,030 --> 00:13:29,520 something in Kotlin. Now sometimes - 321 00:13:29,520 --> 00:13:31,350 and this is one of them - you just can't 322 00:13:31,350 --> 00:13:33,810 avoid using nullable types in Kotlin, and 323 00:13:33,810 --> 00:13:35,760 generally, that's when you're using Java 324 00:13:35,760 --> 00:13:38,640 classes. Now the Asynctask class was 325 00:13:38,640 --> 00:13:40,860 written in Java, well before Kotlin was 326 00:13:40,860 --> 00:13:42,780 created. So if you want to be able to 327 00:13:42,780 --> 00:13:44,730 cancel our task when the Activity gets 328 00:13:44,730 --> 00:13:47,250 destroyed, we're going to have to use a 329 00:13:47,250 --> 00:13:49,320 nullable type here for that. So I'm gonna go 330 00:13:49,320 --> 00:13:51,960 ahead and change that now, so private val 331 00:13:51,960 --> 00:13:54,870 downloadData : We're gonna change this 332 00:13:54,870 --> 00:13:56,070 all here - let's just delete that 333 00:13:56,070 --> 00:13:58,260 entire reference there. So it should 334 00:13:58,260 --> 00:14:01,130 now be private val downloadData : 335 00:14:01,130 --> 00:14:06,260 DownloadData? equals null. 336 00:14:06,260 --> 00:14:08,310 The other thing it should also be is a 337 00:14:08,310 --> 00:14:11,280 var now, and not a val. Now that we've 338 00:14:11,280 --> 00:14:12,690 done that, we can create a new instance 339 00:14:12,690 --> 00:14:15,930 in the downloadUrl function. So we can come 340 00:14:15,930 --> 00:14:20,900 along here and put downloadData equals 341 00:14:20,900 --> 00:14:28,640 DownloadData this, then xmlListView. 342 00:14:28,640 --> 00:14:30,810 Then on the next line, we can change it 343 00:14:30,810 --> 00:14:35,279 to downloadData? dot 344 00:14:35,279 --> 00:14:38,490 execute feedUrl. So whenever we call 345 00:14:38,490 --> 00:14:40,560 functions on our downloadData instance, 346 00:14:40,560 --> 00:14:42,180 we have to use the safe call operator, 347 00:14:42,180 --> 00:14:44,130 and that's because it could now be null. 348 00:14:44,130 --> 00:14:46,080 So you can see that I've added the safe 349 00:14:46,080 --> 00:14:49,380 call in the downloadUrl, on line 48, and 350 00:14:49,380 --> 00:14:51,029 also need to go down to the 351 00:14:51,029 --> 00:14:52,920 onDestroy function, and do the same thing 352 00:14:52,920 --> 00:14:57,870 to that as well - safe call operator 353 00:14:57,870 --> 00:15:00,870 with the question mark there. So, as a 354 00:15:00,870 --> 00:15:02,190 general rule, we should avoid using 355 00:15:02,190 --> 00:15:04,380 nullable types wherever possible, but 356 00:15:04,380 --> 00:15:06,150 sometimes, as I mentioned, we just have to 357 00:15:06,150 --> 00:15:08,190 use them. Alright, so with those changes 358 00:15:08,190 --> 00:15:11,279 now, the code should work, so let's just 359 00:15:11,279 --> 00:15:18,150 check our app to see that it does. So at 360 00:15:18,150 --> 00:15:19,620 the moment, we've got the Free one 361 00:15:19,620 --> 00:15:22,050 working. Let's try another Paid app, or 362 00:15:22,050 --> 00:15:23,370 Paid apps, I should say. You can see we've 363 00:15:23,370 --> 00:15:25,410 got a different set of output there, 364 00:15:25,410 --> 00:15:29,970 Songs, then going back to Free apps. So you can 365 00:15:29,970 --> 00:15:31,980 see that's now working nicely. I'm 366 00:15:31,980 --> 00:15:33,750 choosing, I've chosen different feeds there, as 367 00:15:33,750 --> 00:15:35,400 you saw, and the app displays the data for 368 00:15:35,400 --> 00:15:37,890 the Free apps, Paid apps and Songs. Now 369 00:15:37,890 --> 00:15:39,720 that's working fine, and in case you wondered 370 00:15:39,720 --> 00:15:44,070 when I selected Songs, the Songs feed 371 00:15:44,070 --> 00:15:45,990 doesn't have a summary tag, but the 372 00:15:45,990 --> 00:15:47,430 program doesn't crash so it doesn't put 373 00:15:47,430 --> 00:15:48,930 any text in - it just doesn't put any 374 00:15:48,930 --> 00:15:51,510 text into it. So that's how easy it is to 375 00:15:51,510 --> 00:15:53,370 implement a menu in your 376 00:15:53,370 --> 00:15:56,130 apps. So I'll stop the video here, and in 377 00:15:56,130 --> 00:15:57,870 the next one, we'll add options to toggle 378 00:15:57,870 --> 00:16:00,570 between the Top 10 and Top 25 feeds. 379 00:16:00,570 --> 00:16:04,310 So see you in the next video.