1 00:00:04,740 --> 00:00:07,480 Alright, so at the moment, we've got an 2 00:00:07,480 --> 00:00:09,880 interface that's not terribly pretty, and the 3 00:00:09,880 --> 00:00:11,770 options for formatting the information 4 00:00:11,770 --> 00:00:13,930 are fairly limited when you're using the 5 00:00:13,930 --> 00:00:16,570 basic ArrayAdapter class. But this 6 00:00:16,570 --> 00:00:18,820 example does demonstrate how easy it is 7 00:00:18,820 --> 00:00:20,320 to use the ListView and an Adapter 8 00:00:20,320 --> 00:00:22,930 together. Now if we wanted more control 9 00:00:22,930 --> 00:00:24,849 over exactly what happens in the 10 00:00:24,849 --> 00:00:26,950 ListView, we then have to create our own 11 00:00:26,950 --> 00:00:29,140 Adapter, and we'll actually do that in 12 00:00:29,140 --> 00:00:30,189 the next video. 13 00:00:30,189 --> 00:00:32,619 But what I want to do, though, is go 14 00:00:32,619 --> 00:00:34,540 through and we're going to comment out 15 00:00:34,540 --> 00:00:37,330 the toString method - the to 16 00:00:37,330 --> 00:00:38,710 String method in the FeedEntry class - 17 00:00:38,710 --> 00:00:40,750 just to show that the basic Array 18 00:00:40,750 --> 00:00:42,940 Adapter is using the object's toString 19 00:00:42,940 --> 00:00:45,310 method to display the class data. And 20 00:00:45,310 --> 00:00:47,110 it's also going to show you what the 21 00:00:47,110 --> 00:00:49,060 default toString method produces. So 22 00:00:49,060 --> 00:00:50,160 we're going back to our class, 23 00:00:50,160 --> 00:00:55,320 so we can go to ParseApplications. 24 00:00:55,320 --> 00:00:57,490 And if you remember, it was actually in 25 00:00:57,490 --> 00:00:59,470 MainActivity class FeedEntry, which we 26 00:00:59,470 --> 00:01:01,390 had in our MainActivity. So we're gonna 27 00:01:01,390 --> 00:01:05,170 comment out the function - the toString 28 00:01:05,170 --> 00:01:06,970 function. We're just gonna literally just 29 00:01:06,970 --> 00:01:09,819 select all of it, up to and including the 30 00:01:09,819 --> 00:01:13,829 closing right curly brace. Comment that out, 31 00:01:13,829 --> 00:01:15,789 and if we actually run the app again 32 00:01:15,789 --> 00:01:22,700 now, 33 00:01:22,700 --> 00:01:24,500 you can see that we're just getting 34 00:01:24,500 --> 00:01:26,180 the full class name and this strange 35 00:01:26,180 --> 00:01:27,920 hexadecimal number here, that's actually 36 00:01:27,920 --> 00:01:29,899 changing for each object. 37 00:01:29,899 --> 00:01:32,689 Well that number's the hash code of each 38 00:01:32,689 --> 00:01:35,299 instance of the FeedEntry class. So it's 39 00:01:35,299 --> 00:01:36,920 not very user friendly and we're not 40 00:01:36,920 --> 00:01:38,509 seeing any of the actual data in the 41 00:01:38,509 --> 00:01:40,640 objects. So that's why it was a good idea 42 00:01:40,640 --> 00:01:43,340 to override the toString 43 00:01:43,340 --> 00:01:45,469 function, so that we could see the actual 44 00:01:45,469 --> 00:01:47,060 data rather than this default 45 00:01:47,060 --> 00:01:49,880 representation of the objects. So I 46 00:01:49,880 --> 00:01:51,319 mentioned earlier that we have to cater 47 00:01:51,319 --> 00:01:53,899 for the Activity being destroyed while 48 00:01:53,899 --> 00:01:56,479 our AsyncTask's still running. Now that's 49 00:01:56,479 --> 00:01:58,970 quite easy. We can just cancel the task 50 00:01:58,970 --> 00:02:01,640 in the Activity's onDestroy method. Now 51 00:02:01,640 --> 00:02:03,799 we're going to have to move the declaration of 52 00:02:03,799 --> 00:02:06,170 downloadData to make it available in 53 00:02:06,170 --> 00:02:08,449 onDestroy, but let's go ahead and write 54 00:02:08,449 --> 00:02:10,970 the onDestroy method first. So I'm going 55 00:02:10,970 --> 00:02:14,750 to go back to our MainActivity, and we're 56 00:02:14,750 --> 00:02:15,829 going to put this just below the 57 00:02:15,829 --> 00:02:21,049 onCreate, before the companion object 58 00:02:21,049 --> 00:02:24,410 line. And we'll override - we're looking for 59 00:02:24,410 --> 00:02:27,680 onDestroy. So we're getting Android 60 00:02:27,680 --> 00:02:30,079 Studio to write the onDestroy stub 61 00:02:30,079 --> 00:02:32,959 for us - or create the stub for us. So 62 00:02:32,959 --> 00:02:35,120 in terms of the calls, we're going to 63 00:02:35,120 --> 00:02:36,650 leave the super.onDestroy in there, 64 00:02:36,650 --> 00:02:38,329 and we're gonna add this one extra line. 65 00:02:38,329 --> 00:02:40,910 So it's gonna be downloadData dot 66 00:02:40,910 --> 00:02:45,079 cancel parentheses true. Now at the 67 00:02:45,079 --> 00:02:46,760 moment, downloadData is local to the 68 00:02:46,760 --> 00:02:48,739 onCreate method, so to get this to 69 00:02:48,739 --> 00:02:50,299 work we need to declare it at the top of 70 00:02:50,299 --> 00:02:52,130 the class instead. So I'm going to come 71 00:02:52,130 --> 00:02:53,569 up to the top of the class and do just 72 00:02:53,569 --> 00:02:55,250 that, and we're going to put that just 73 00:02:55,250 --> 00:02:59,870 below the initial TAG here. So 74 00:02:59,870 --> 00:03:04,670 val downloadData is equal to 75 00:03:04,670 --> 00:03:07,340 DownloadData with capital Ds for both 76 00:03:07,340 --> 00:03:11,120 words, in parentheses this comma space 77 00:03:11,120 --> 00:03:14,650 xmlListView. 78 00:03:14,650 --> 00:03:16,849 Now I'm getting this warning here, or 79 00:03:16,849 --> 00:03:18,829 this error; public properly exposes its 80 00:03:18,829 --> 00:03:21,829 private type DownloadData. Now all 81 00:03:21,829 --> 00:03:23,419 properties in Kotlin are public by 82 00:03:23,419 --> 00:03:26,180 default, so downloadData's public. But 83 00:03:26,180 --> 00:03:28,540 as its type in our private class - 84 00:03:28,540 --> 00:03:31,519 come down here and have a look. We've got 85 00:03:31,519 --> 00:03:33,640 the type set for private here in on line 52 - 86 00:03:33,640 --> 00:03:35,990 that's what's causing a problem. 87 00:03:35,990 --> 00:03:37,850 So you can't expose an object whose type 88 00:03:37,850 --> 00:03:40,070 is private, so we have to make download 89 00:03:40,070 --> 00:03:41,870 Data private, which it really should be 90 00:03:41,870 --> 00:03:43,670 anyway, even if Kotlin doesn't enforce 91 00:03:43,670 --> 00:03:45,530 this or didn't enforce this. There's no 92 00:03:45,530 --> 00:03:47,090 reason why anything 93 00:03:47,090 --> 00:03:49,310 outside MainActivity should be using 94 00:03:49,310 --> 00:03:51,740 our DownloadData object anyway. So we're 95 00:03:51,740 --> 00:03:53,150 gonna go back up and change this - it 96 00:03:53,150 --> 00:03:56,060 should be private val. So we'll add the 97 00:03:56,060 --> 00:03:59,360 keyword private, to satisfy Kotlin there. 98 00:03:59,360 --> 00:04:01,940 Alright, so there's no error, but at the 99 00:04:01,940 --> 00:04:04,820 moment it won't work though. So why won't 100 00:04:04,820 --> 00:04:06,530 this work? Have a think about what's 101 00:04:06,530 --> 00:04:07,930 being passed to the DownloadData 102 00:04:07,930 --> 00:04:11,360 constructor here, and when we can 103 00:04:11,360 --> 00:04:13,760 reasonably expect things to exist. Pause 104 00:04:13,760 --> 00:04:15,320 the video now, and then I'll explain why 105 00:04:15,320 --> 00:04:18,220 the code won't work, when you come back. 106 00:04:18,220 --> 00:04:21,290 Alright, so did you figure out why? Well, 107 00:04:21,290 --> 00:04:23,720 what's wrong with that code? Well the 108 00:04:23,720 --> 00:04:25,970 problem's caused by passing the reference 109 00:04:25,970 --> 00:04:29,150 to our ListView, to the constructor. Now 110 00:04:29,150 --> 00:04:30,620 none of our widgets will exist until 111 00:04:30,620 --> 00:04:33,290 after the call to setContentView, in 112 00:04:33,290 --> 00:04:36,170 the onCreate method, and we saw this, if 113 00:04:36,170 --> 00:04:38,390 you recall, in the calculator app. The 114 00:04:38,390 --> 00:04:41,420 solution is to use by lazy, so that the 115 00:04:41,420 --> 00:04:43,430 initialisation isn't performed until the 116 00:04:43,430 --> 00:04:45,410 first time we need to use our download 117 00:04:45,410 --> 00:04:47,570 Data object. So let's go ahead and change 118 00:04:47,570 --> 00:04:49,610 that. So it should be private val 119 00:04:49,610 --> 00:04:52,640 downloaData by lazy, and we'll get rid 120 00:04:52,640 --> 00:04:57,080 of the equal sign, so by lazy. Then we 121 00:04:57,080 --> 00:04:58,780 put left and right curly braces, 122 00:04:58,780 --> 00:05:00,830 and we put 'this' in the left and right 123 00:05:00,830 --> 00:05:03,890 curly braces, like so. So by the time we 124 00:05:03,890 --> 00:05:05,900 use downloadData, the layout's been 125 00:05:05,900 --> 00:05:08,450 created and the widgets are available in 126 00:05:08,450 --> 00:05:10,490 our code. So if you're not clear about 127 00:05:10,490 --> 00:05:12,800 that, review the discussion that we had 128 00:05:12,800 --> 00:05:14,360 about this in the last section, about 129 00:05:14,360 --> 00:05:17,240 using by lazy. Alright, so that's it - the 130 00:05:17,240 --> 00:05:19,490 Activity's destroyed while our Async 131 00:05:19,490 --> 00:05:20,870 Task's running and the task will be 132 00:05:20,870 --> 00:05:23,660 cancelled. Now the other thing we need to 133 00:05:23,660 --> 00:05:25,640 do is, obviously, comment out our val 134 00:05:25,640 --> 00:05:28,640 downloadData, and what I didn't do was, I 135 00:05:28,640 --> 00:05:30,320 probably should have actually copied 136 00:05:30,320 --> 00:05:34,250 this line 41, and actually copied it over 137 00:05:34,250 --> 00:05:36,020 and sort of pasted it or moved it, I 138 00:05:36,020 --> 00:05:38,660 should say, back up to the reference here 139 00:05:38,660 --> 00:05:40,520 on line 34, because obviously we've got 140 00:05:40,520 --> 00:05:42,560 the definition of downloadData in two 141 00:05:42,560 --> 00:05:44,450 places now. So, obviously, that's another 142 00:05:44,450 --> 00:05:45,560 reason why we would have got an error 143 00:05:45,560 --> 00:05:47,570 when we're actually running this. But the 144 00:05:47,570 --> 00:05:49,770 point is, that should not be in there, so I'm 145 00:05:49,770 --> 00:05:51,270 going to actually remove that now - remove that 146 00:05:51,270 --> 00:05:53,789 entire definition on line 41. That's in 147 00:05:53,789 --> 00:05:56,069 the onCreate function, because obviously 148 00:05:56,069 --> 00:05:58,590 now, we've got the definitions showing up 149 00:05:58,590 --> 00:06:01,379 here on line 34 in our MainActivity 150 00:06:01,379 --> 00:06:04,229 class. And because, again, we're using by 151 00:06:04,229 --> 00:06:06,900 lazy, the values are only going to get 152 00:06:06,900 --> 00:06:10,169 updated when they're first accessed. Alright, 153 00:06:10,169 --> 00:06:12,990 so let's just run this again, to make 154 00:06:12,990 --> 00:06:19,319 sure it works. Alright, you can see that that's 155 00:06:19,319 --> 00:06:20,909 still working. What I'll do is, I'll also 156 00:06:20,909 --> 00:06:23,069 make a change and put back the to 157 00:06:23,069 --> 00:06:24,599 String again, just so we can see the 158 00:06:24,599 --> 00:06:28,259 normal values again. Then run it 159 00:06:28,259 --> 00:06:35,669 again. Okay, so that's working nicely. So 160 00:06:35,669 --> 00:06:37,409 now if the Activity is destroyed while 161 00:06:37,409 --> 00:06:40,169 our AsyncTask's running, the task will be 162 00:06:40,169 --> 00:06:42,330 cancelled. Now by the way, the boolean 163 00:06:42,330 --> 00:06:47,669 argument to the cancel function - I'm 164 00:06:47,669 --> 00:06:49,409 talking about this on line 40, code on line 165 00:06:49,409 --> 00:06:52,229 47 - that tells Android that it can 166 00:06:52,229 --> 00:06:53,669 interrupt the task, and that's why we're 167 00:06:53,669 --> 00:06:55,860 passing true there, to say if that is okay 168 00:06:55,860 --> 00:06:58,319 to do that. Now that may seem like a 169 00:06:58,319 --> 00:07:00,659 strange thing to have to specify when 170 00:07:00,659 --> 00:07:03,120 cancelling a task. However, you may want 171 00:07:03,120 --> 00:07:04,949 the task to complete anyway, depending on 172 00:07:04,949 --> 00:07:07,169 well it's doing. What you don't want, and 173 00:07:07,169 --> 00:07:09,479 what would cause a crash, is if you then 174 00:07:09,479 --> 00:07:11,250 try to pass its results back to the 175 00:07:11,250 --> 00:07:13,380 Activity that's being destroyed. So there 176 00:07:13,380 --> 00:07:14,940 are situations where you'd want to pass 177 00:07:14,940 --> 00:07:17,580 false to the cancel function. Alright, 178 00:07:17,580 --> 00:07:19,469 so I'm gonna stop the video here, and in 179 00:07:19,469 --> 00:07:20,849 the next one we're gonna start creating 180 00:07:20,849 --> 00:07:23,250 our own adapter. And this gives us far 181 00:07:23,250 --> 00:07:25,169 more control over what appears in the 182 00:07:25,169 --> 00:07:26,880 ListView, and it's also a good way to 183 00:07:26,880 --> 00:07:29,400 understand how adapters work. So I'll see 184 00:07:29,400 --> 00:07:32,090 you in the next video.