1 00:00:05,550 --> 00:00:10,800 Alright, so it's time to start creating our app to download the flickr feed and pass out the information 2 00:00:10,800 --> 00:00:14,420 that we need, so we need to start a new project in Android Studio. 3 00:00:14,420 --> 00:00:23,810 So I'm going to do that, and I'm going to call this one Flickr Browser. The company domain, 4 00:00:23,810 --> 00:00:31,600 I'm going to have learn programming dot Academy as I've done for other videos in this course, and as 5 00:00:31,600 --> 00:00:35,980 usual tick the box to include Kotlin support if you're using Kotlin, and leave it 6 00:00:35,980 --> 00:00:40,330 unticked if you're using Java. 7 00:00:40,330 --> 00:00:46,210 Click on next, and on this screen we're going to choose API 17 as we normally do, 8 00:00:46,210 --> 00:00:53,730 we've done for other projects in this course, click on next. Now in the template screen here I've currently got 9 00:00:53,730 --> 00:00:55,800 the choices that you can see on screen. 10 00:00:55,800 --> 00:01:00,510 However keep in may that Google do change the templates from time to time, and the options you've got 11 00:01:00,510 --> 00:01:02,550 available may be different. 12 00:01:02,550 --> 00:01:07,560 And as I mentioned in the templates video in section 3, these are just templates that we can add and 13 00:01:07,560 --> 00:01:09,300 remove code as needed. 14 00:01:09,300 --> 00:01:13,830 So it makes sense to choose a template that best fits your application, and there should always be something 15 00:01:13,830 --> 00:01:19,020 like the empty activity, that'll create a project with very little code filled in for you. 16 00:01:19,020 --> 00:01:24,960 Now this app we're creating is going to use a menu, but we won't be using the floating action button because 17 00:01:24,960 --> 00:01:31,410 you can see at the bottom of the basic activity template, this one here, basic activity has both a menu and 18 00:01:31,410 --> 00:01:37,580 a fab, a floating action button, and you can see the menu at the top half here of the templates image. 19 00:01:37,580 --> 00:01:42,810 Now I don't want both, but it's easier to remove code than go to the trouble of adding code for the menu, 20 00:01:42,810 --> 00:01:46,590 back in. So basic activity is the one that we're going to use here. 21 00:01:46,590 --> 00:01:50,970 Once again if you have different options in your version of Android Studio when you come to watch this 22 00:01:50,970 --> 00:01:56,980 video, choose the simplest available template that includes a menu. So I'm going to click on next now that I've chosen 23 00:01:56,980 --> 00:02:05,300 basic activity. I'm going to leave all these names at the moment as the default. While we're creating this 24 00:02:05,300 --> 00:02:11,570 app I'm going to show you how to manually rename and change things anyway. So with that done I'm going to click on finish. We're going to wait 25 00:02:11,570 --> 00:02:20,900 while Android Studio creates the project for us. 26 00:02:20,900 --> 00:02:25,760 Alright so you can see we've just about finished, and our default application's being created, 27 00:02:25,760 --> 00:02:33,170 and we should see two created layouts here, and I'll just expand up here so we can have a look, look in the res folder. 28 00:02:33,170 --> 00:02:38,750 And we just need to give it a little bit longer to complete, and then we'll be able to see. Alright there we go. I can 29 00:02:38,750 --> 00:02:40,700 see now that in our layout folder, 30 00:02:40,700 --> 00:02:46,580 we've got activity main and content main dot xml, and we saw those in the template videos. 31 00:02:46,580 --> 00:02:48,770 Now Google may decide to change that, 32 00:02:48,770 --> 00:02:52,370 so if you only got a single layout xml file created that's fine. 33 00:02:52,370 --> 00:02:57,410 Just make your changes in that one. OK now I want to add logging code to our app. 34 00:02:57,410 --> 00:03:02,120 I mentioned this in the button counter app, in that section of the course, when we looked at the activity 35 00:03:02,120 --> 00:03:05,850 life cycle, but I'm going to go over it briefly again here. 36 00:03:05,850 --> 00:03:11,060 Logging when your methods start and end is one of the most useful techniques you can use when trying 37 00:03:11,060 --> 00:03:14,540 to understand how the Android framework operates. 38 00:03:14,540 --> 00:03:19,030 So I'm going to leave the user interface, the creation of that, until later. 39 00:03:19,030 --> 00:03:22,400 We're going to start by downloading the data and then parsing it. 40 00:03:22,400 --> 00:03:26,810 So we're going to be writing a lot of output to the log cat, so that we can check what's happening and 41 00:03:26,810 --> 00:03:28,760 see that things are working. 42 00:03:28,760 --> 00:03:35,420 Now this app will also be using an async task to perform the download on a separate thread. So that stops 43 00:03:35,420 --> 00:03:41,400 the user interface from appearing to hang when a potentially long running task is going on. 44 00:03:41,400 --> 00:03:46,400 Now it's a good idea to do things like downloading or reading lots of data from a file or database in 45 00:03:46,400 --> 00:03:47,930 a separate thread. 46 00:03:47,930 --> 00:03:54,890 In fact the http class, which we're going to use, will give an error if we try to download on the main user 47 00:03:54,890 --> 00:03:56,210 interface thread. 48 00:03:56,210 --> 00:04:01,280 Now messaging threads can be tricky but the async task does all the hard work for us. 49 00:04:01,280 --> 00:04:06,290 So we're going to take a similar approach to the top 10 downloader app, but I'm going to be doing things 50 00:04:06,290 --> 00:04:12,200 slightly differently when we come to use the data downloaded by the async task. 51 00:04:12,200 --> 00:04:16,519 Now as I mentioned in the introduction, the app's also going to be using an adapter 52 00:04:16,519 --> 00:04:21,529 when we come to display the data. Now the way all the various classes work together can take a while 53 00:04:21,529 --> 00:04:22,760 to understand, 54 00:04:22,760 --> 00:04:28,100 so what I'm going to do is log a message each time a method's called. Now the messages in the log will 55 00:04:28,100 --> 00:04:33,080 then show what methods are being called, and when. This allows us to see what's happening, 56 00:04:33,080 --> 00:04:38,900 and the order that things are being called. Now those log entries will make it much easier to understand 57 00:04:38,900 --> 00:04:40,700 how the app works. 58 00:04:40,700 --> 00:04:44,900 Now up until now we've used a private variable for the log tag. 59 00:04:44,900 --> 00:04:50,820 So I'll start this app by showing you another way to define it, using something called a companion object. 60 00:04:50,820 --> 00:04:57,300 Now Kotlin doesn't have a direct equivalent to Java's static variables but we can create something similar. 61 00:04:57,300 --> 00:05:05,020 Now I'm going to add it to the end of our main activity class, so let's open that up, and down here before the last right 62 00:05:05,020 --> 00:05:11,310 curly brace, I'm going to type companion, object and just press enter there. 63 00:05:11,310 --> 00:05:20,740 OK like so, and then within the companion object we're going to type private const val, TAG in upper case, equals 64 00:05:20,740 --> 00:05:26,070 double quotes MainActivity. So that's our companion object. 65 00:05:26,070 --> 00:05:32,410 And then what we're going to do is come up to our onCreate method up here, and we're going to actually to use that. 66 00:05:32,410 --> 00:05:41,770 So basically on the first line, before the super.OnCreate code, we're going to type Log dot d parentheses TAG 67 00:05:41,770 --> 00:05:53,840 in uppercase, comma space, then onCreate in double quotes, called. OK we're also going to add the same thing, a log 68 00:05:53,840 --> 00:05:58,550 entry to onCreateOptionsMenu and on items, onOptionsItemsSelected. 69 00:05:58,550 --> 00:06:06,740 So I'm going to take a copy of that line, first line of the onCreateOptionsMenu, just put it in there. This time we'll 70 00:06:06,740 --> 00:06:15,730 change it though, so it's onCreateOptionsMenu, and for the onOptionsItemsSelected, 71 00:06:15,730 --> 00:06:31,020 we're going to put a Log.d before the return when, so that's onOptionsItemSelected called, as you can see. OK. 72 00:06:31,020 --> 00:06:35,660 That's a fairly standard debug logging line that we've used a few times now. 73 00:06:35,660 --> 00:06:38,040 So what I'm going to do is run this to make sure that it's working, 74 00:06:38,040 --> 00:06:41,680 so we're going to start the app, and I'm going to start my emulator. 75 00:06:41,680 --> 00:06:53,770 It's not started on this device, so I'll just fast-forward this one starting. OK, 76 00:06:53,770 --> 00:06:55,130 there's our app running, and 77 00:06:55,130 --> 00:07:01,190 if you go back to log cat, we should be able to see that output hopefully, and what I can do to make sure we 78 00:07:01,190 --> 00:07:09,770 can actually filter on main activity, so let's try doing that, and there we go, main activity. 79 00:07:09,770 --> 00:07:14,930 That's enough there, you can see we've got our two options at the moment, onCreate is being called, and on 80 00:07:14,930 --> 00:07:21,340 CreateOptionsMenu has also been called. So what have we done differently, and perhaps more importantly, 81 00:07:21,340 --> 00:07:23,230 why am I showing you this. 82 00:07:23,230 --> 00:07:28,300 Well to answer the second question first, I'm showing you this because you're going to see it being used. 83 00:07:28,300 --> 00:07:33,760 It's the code that'll be generated automatically, when you use Android Studio to convert Java code 84 00:07:33,760 --> 00:07:35,600 to Kotlin for one thing. 85 00:07:35,600 --> 00:07:39,730 Now I'm not going to show you how to convert Java to Kotlin yet, and that's mainly because it's too 86 00:07:39,730 --> 00:07:46,270 easy just do that yet and end up not really writing Kotlin. But you'll see these companion objects 87 00:07:46,270 --> 00:07:50,810 like we've created here, used for things like analog tag. 88 00:07:50,810 --> 00:07:56,900 So it's important to be familiar with code like this, and again this code I'm talking about is the code on line 44. 89 00:07:56,900 --> 00:08:04,040 Now Java has things called static fields, and these belong to the class rather than to the instances 90 00:08:04,040 --> 00:08:07,400 of the class. Now don't worry too much about that. 91 00:08:07,400 --> 00:08:13,490 We're working with Kotlin not Java after all, but one reason for using those static fields is that there's 92 00:08:13,490 --> 00:08:15,920 only one copy created. 93 00:08:15,920 --> 00:08:23,220 Now if we used a normal variable, each instance of main activity would create a new copy of the tag variable. 94 00:08:23,220 --> 00:08:29,100 Now obviously that's not a good use of memory because each copy would contain exactly the same text, 95 00:08:29,100 --> 00:08:34,970 and if we created 1000 instances of main activity, you'd have a thousand variables all with exactly the 96 00:08:34,970 --> 00:08:35,900 same value, 97 00:08:35,900 --> 00:08:41,870 the string main activity, so that's nearly 12K of ram used up, which is a bit of a waste to put it mildly. 98 00:08:41,870 --> 00:08:47,310 So that's one reason for using class variables rather than instance variables. 99 00:08:47,310 --> 00:08:52,610 Now the equivalent way to do that in Kotlin is to use a companion object, and declare tag 100 00:08:52,610 --> 00:08:57,140 in this case, in there. Now unfortunately it's not exactly equivalent. 101 00:08:57,140 --> 00:09:03,740 In fact because we've used const here on line 45, we end up with a tag being placed in line. 102 00:09:03,740 --> 00:09:10,010 So that means the text is copied into our code, every where that we've used the tag variable. 103 00:09:10,010 --> 00:09:14,690 Now that may not make much sense, so I'm going to convert the code to Java to show what's being 104 00:09:14,690 --> 00:09:16,850 produced for us. 105 00:09:16,850 --> 00:09:20,600 Now if you don't know Java, don't worry too much about the code we're about to see. 106 00:09:20,600 --> 00:09:27,190 The point is to show you how our tag variable is really used where the Kotlin program is compiled. 107 00:09:27,190 --> 00:09:32,230 Now converting Kotlin to Java is currently a two step process. 108 00:09:32,230 --> 00:09:39,600 So first thing is the Decompile Kotlin to Java option, this is on the tools Kotlin menu, 109 00:09:39,600 --> 00:09:44,590 Decompile Kotlin to Java, which is currently greyed. So it's basically not available yet, 110 00:09:44,590 --> 00:09:50,720 but what we can do instead, is use the Show Kotlin Bytecode option to see what our Kotlin code compiles 111 00:09:50,720 --> 00:10:02,830 to. So basically, tools, Kotlin, Show Kotlin Bytecode. 112 00:10:02,830 --> 00:10:10,040 If I bring this over a little bit more, you can see all this strange code in the Kotlin Bytecode pane. Now there's very few 113 00:10:10,040 --> 00:10:13,990 people on the planet who can understand this Bytecode. 114 00:10:13,990 --> 00:10:16,190 Now I'm not going to attempt to make sense of it. 115 00:10:16,190 --> 00:10:23,030 It's intended for the JVM to execute, not for humans to read, but what we can do is click the decompile 116 00:10:23,030 --> 00:10:25,960 button to convert it back to Java. 117 00:10:25,960 --> 00:10:33,500 So go go ahead and do that, and I'm going to close this window, 118 00:10:33,500 --> 00:10:37,070 and this is the decompiled version converted back to Java. 119 00:10:37,070 --> 00:10:42,950 Now this might look horrible, but if we scroll down and have a look we can see the Log.d calls 120 00:10:42,950 --> 00:10:49,410 in each of the methods - Log.d again, Log.d and Log.d. 121 00:10:49,410 --> 00:10:56,480 So notice that the string main activity is actually repeated in each of those calls, three times there. 122 00:10:56,480 --> 00:11:03,020 That's what I meant by the tag value being placed in line. Now our attempt to save memory by using 123 00:11:03,020 --> 00:11:06,790 the Kotlin equivalent of a static field hasn't worked out too well. Our 124 00:11:06,790 --> 00:11:15,400 code's duplicating the value of tag, each time we do any logging. OK I'm going to close the decompiled Java tab here, and 125 00:11:15,400 --> 00:11:21,290 I've already closed the Kotlin Bytecode pane. I'm going to go back to our code now on the screen. So you'll almost 126 00:11:21,290 --> 00:11:26,300 certainly come across code that uses a companion object like we've used here. 127 00:11:26,300 --> 00:11:31,130 But I'm going to suggest that you don't do it in your activities. So just to be clear I'm not saying 128 00:11:31,130 --> 00:11:33,140 that you shouldn't use companion objects. 129 00:11:33,140 --> 00:11:36,440 We're using them in some of our code and they do have their uses. 130 00:11:36,440 --> 00:11:39,110 What I'm saying is that I wouldn't use one here. 131 00:11:39,110 --> 00:11:43,250 Now one reason is, we're only going to have one instance of main activity anyway. 132 00:11:43,250 --> 00:11:48,260 Well now we may create thousands of instances of some classes, such as the feed entry class in our Top 133 00:11:48,260 --> 00:11:53,480 10 downloader. We created an instance of feed entry for each row in the list view. 134 00:11:53,480 --> 00:11:59,390 So we definitely created quite a few of those, but it's very rare for an app to create several instances 135 00:11:59,390 --> 00:12:01,370 of an activity at the same time, 136 00:12:01,370 --> 00:12:06,260 so the benefit of a static field in saving memory doesn't really apply here. 137 00:12:06,260 --> 00:12:11,810 Now if you're comfortable with Java, and want to check the decompiled code again for, after removing const 138 00:12:11,810 --> 00:12:16,070 from line 45, you'll see why that's also not a good option. 139 00:12:16,070 --> 00:12:24,640 So I'm going to comment out our companion object code anyway, rather than deleting it, so it's available for reference. 140 00:12:24,640 --> 00:12:30,560 Now I've covered this now, because it's about now that you probably want to know about the lint boarding 141 00:12:30,560 --> 00:12:32,920 when we declared tag as a normal variable. 142 00:12:32,920 --> 00:12:40,080 So let's just come up here and do that first, right at the top, we're going to do it as the first entry inside the class, so private 143 00:12:40,080 --> 00:12:50,230 val, TAG in uppercase equals, in double quotes MainActivity, and we get a weak warning that private property 144 00:12:50,230 --> 00:12:56,380 tag doesn't match, so come over here, private property name tag doesn't match regex. 145 00:12:56,380 --> 00:13:01,860 Now we're getting that warning because variable names should begin with a lower case letter. Constants 146 00:13:01,860 --> 00:13:05,290 should be in all capitals and we're using tag as a constant, 147 00:13:05,290 --> 00:13:07,360 but we haven't declared it to be one. 148 00:13:07,360 --> 00:13:11,980 We've just seen why we don't want to do that, but it does mean we get this warning. 149 00:13:11,980 --> 00:13:16,720 Now one way to remove this warning is to name tag in lowercase. 150 00:13:16,720 --> 00:13:19,150 That's an option but not something we want to do, 151 00:13:19,150 --> 00:13:23,680 if we're working with XML for example. There's all sorts of examples where we might want to refer 152 00:13:23,680 --> 00:13:29,130 to tags, and using tag in lowercase for our logging would just cause confusion. 153 00:13:29,130 --> 00:13:30,850 Now I don't actually have an answer for this. 154 00:13:30,850 --> 00:13:37,120 The best solution I can think of would be to disable the lint check for this line of code, but unfortunately 155 00:13:37,120 --> 00:13:38,740 that's not possible at the moment. 156 00:13:38,740 --> 00:13:45,510 It is actually worth clicking on TAG, and then come over here and check it on the light bulb options, to see 157 00:13:45,510 --> 00:13:48,540 if there's an option to suppress the warning in the future. 158 00:13:48,540 --> 00:13:50,810 For now I'm just going to live with the warning. 159 00:13:50,810 --> 00:13:55,050 Now that's not ideal but at the moment it's the best option we have available. 160 00:13:55,050 --> 00:14:02,640 OK, so moving. Now as I mentioned previously we don't need the floating action bar code in the onCreate method. So, 161 00:14:02,640 --> 00:14:05,880 that's because we're not using the floating action button in this app. 162 00:14:05,880 --> 00:14:09,580 So I'm going to go ahead and delete that code, that's this code here from fab.setOn 163 00:14:09,580 --> 00:14:18,780 ClickListener, and comment all that out, like so, and the other thing I'm going to do, is actually add a log entry for when the 164 00:14:18,780 --> 00:14:28,380 method ends. So I'm going to do a Log.d after that, parentheses TAG comma double quotes onCreate ends. 165 00:14:28,380 --> 00:14:33,240 So each time this onCreate function is called from now on, we'll see the message "onCreate called" 166 00:14:33,240 --> 00:14:37,650 when the function starts, and "onCreate ends" when it finishes. 167 00:14:37,650 --> 00:14:42,450 Now I'm not going to be including logging like this in every single function, but I will add it to the 168 00:14:42,450 --> 00:14:46,770 interesting ones so that we can see the flow of the program when it runs. 169 00:14:46,770 --> 00:14:50,580 Now Android Studio should also remove the fab imports automatically, 170 00:14:50,580 --> 00:14:56,420 but if it doesn't, they'll appear in grey to show they're not being used. So scroll up to the top and have a look at our imports. 171 00:14:56,420 --> 00:15:03,770 In my case you can see they've actually being removed, and I'll put this back just to show you what I mean. 172 00:15:03,770 --> 00:15:13,650 And we can see how they're added automatically, and if I comment that out again, they're actually removed, 173 00:15:13,650 --> 00:15:18,660 see the snack bar gets removed for us automatically in the imports. Well there's actually three, there's a floating action 174 00:15:18,660 --> 00:15:21,490 button, a snack bar and then the Android.view.view, and 175 00:15:21,490 --> 00:15:27,030 you can see that they've all, they're now no longer showing in the input section. 176 00:15:27,030 --> 00:15:29,280 Alright so this video's got quite long. Our 177 00:15:29,280 --> 00:15:34,200 basic project has been set up, so I'm gonna stop the video here, and in the next video we'll start looking 178 00:15:34,200 --> 00:15:38,180 at downloading our json data. So I'll see you in that next video.