Modern Android development: Android Jetpack, Kotlin, and more (Google I/O 2018)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[MUSIC PLAYING] CHET HAASE: Hello. Welcome to another talk. Welcome to Modern Android Development. I should point out, before we start, that this sun is a lot brighter than I am, so we may have to do this. ROMAIN GUY: So we can either put on the glasses and not see the slides, or don't put on the glasses and not see anything. So that's going to be fun. CHET HAASE: We'll see how this goes today. Welcome to Modern Android Development. I'm Chet Haase from the Android toolkit team. ROMAIN GUY: And I'm Romain Guy from the Android framework team slash something. CHET HAASE: And we're going to talk about a bunch of stuff that you probably already know, but it occurred to us that we have given you advice and information about how to develop good apps for Android over the years. And that information has changed over the years as we've introduced new capabilities, new APIs, new performance on the platform, all kinds of things. And so it's a little confusing. You could go search for information even on some of our docs site, and maybe get information that doesn't really apply to a lot of situations currently. So we wanted to wrap it all together and say, here's our current 2018 view of the important things to think about in Android. ROMAIN GUY: Android is 10 years old this year, and yeah, like Chet said, a lot of outdated information. Sometimes, I see blogs on stack overflow, someone being really mad about something that we said 10 years ago. Don't be mad. It's OK. Things change. Things evolve. It's not because we hate you. It's not because we were wrong. It's because it was a different time-- different needs, different devices. So we're going to talk about some of that. Just to make sure you understand the difference between the modern way of doing things and the old way of doing things, we have a slight hint on the slides. So some of the slides are going to look like this. CHET HAASE: So let us begin. So let's take a look at a timeline. This is sort of all the history of Android over time. So 1.0 came out in 2008, and then apparently, we didn't do much for several years. [LAUGHTER] I don't know what was going on there. I just couldn't think of the things to put in there. Optimize, optimize, optimize. And then Android Studio came out. What's that? ROMAIN GUY: According to the web, we were busy building bad APIs. [LAUGHTER] CHET HAASE: Apparently, those weren't the ones you wanted, so we've worked better at that over the years. So Android Studio came out, so we changed from Eclipse into Android Studio, where now, we were building in richer capabilities than we could at the time. Art came out. It was off by default in KitKat, and it was the only runtime in Lollipop. This is huge, as you'll see in some of our recommendations there, because it really has changed, over time, the way we look at the way you should write your code. Prior Dalvik information does not necessarily apply in an Art world. Recycler view was released. Important because it was a better version of List View with more flexibility. But also, we started releasing components in the support library disconnected from platform releases, which means you could use these new capabilities in your applications across all the releases that you cared about. A little while later, we had Constraint Layout built into Android Studio-- a richer way of actually designing your APIs, as opposed to the rich way of typing XML directly. Kotlin-- I think that came out last year. I don't know. Some IO conference or something. Architecture Components-- these were announced last year. 1.0 in the fall. New way of doing things, where we are trying to solve, or at least help with, a lot of complex problems with Android, and taking feedback from the community and iterating on that to create developer APIs that make things easier for you. That is the whole goal. Studio Profilers, a much richer way for actually figuring out what the performance metrics are for your application. KTx, the extension library that came out a couple of months ago for Kotlin. And recently, the Paging Library came out and went 1.0 just this week. So this is sort of a scope of some of the things that have happened over time. I'm pretty sure there was more going on between 2008 and 2013. I just can't remember what it was. ROMAIN GUY: All right. We're going to start with tools. Here's a tool that you may know. How many of you have used this tool, Hierarchy Viewer? Oh, that's pretty good. Not everyone. So that was our tool called Hierarchy Viewer. It was part of the SDK. It was a stand alone application. There was actually another version before that one. That was the one that I originally wrote in a weekend because I needed a debugging tool to optimize the platform. And for some reason, we started shipping it in the SDK. It wasn't the fastest tool. It wasn't the prettiest tool. Actually, this one was built by someone who, funnily enough, was spending a lot of time actually sleeping at their desk. That was very interesting. I never used that technique before. It didn't quite work. So now, we replaced it with something much better, called Layout Inspector. It's part of Android Studio. One of the nice benefits is that you can open multiple inspections at once. It's a lot, lot faster. So if you haven't used that tool, go use it. It's a very easy way to analyze your hierarchy and debug various things like embedding and margining, and even performance sometimes, if you have too many views that overlap each other. Here's another one that's the old way of profiling the code. That was called Trace View. So Trace View is a tool that already existed when I joined the Android team in 2007, so it's been around for quite a while. Here, we see it in action inside of Eclipse. It used to be its own stand alone tool. So one of the issues that we had with Trace View is the original version was an instrumented profiler, so there was a lot of overhead. It was running on every method that was invoked. It was running in interpreting mode. And so you couldn't really trust the numbers. So when it said, this method took three milliseconds, that wasn't true. The method actually was a lot faster than that, and the only thing you could do is compare the relative time between different methods. And even that was difficult because if a method was invoking native code, the native code was not affected. So any method invoking native code was skewed because numbers were just all so wrong. Over the years, we added sampling profiling to this tool. But still, it was very difficult to use. Only a few of us even were using it internally because it wasn't that great. A few years later, thankfully, we introduced Systrace. So the big benefit of Systrace over Trace View is that it gives you a comprehensive view of the entire system. Trace View tells you how much time you're spending on every line of code inside your application, basically. But sometimes, performance issues come from somewhere else in the system. Maybe you're blocked on something that's in a different process. So Systrace gives you that view that you needed. Before that, we were completely in the blind. And now, we have new profilers that have been introduced in Android Studio. I think they're part of 3.2 or 3.1. I don't really remember. But if you go to the Profiler tab, you're going to see a real time graph of the CPU usage of your application and the memories [INAUDIBLE] of your application. And if you double-click on the CPU graph, you're going to get to that view. It looks very similar to Trace View. Again, it's a lot faster, and it lets you do native code profiling, instrumented profiling, sampling profiling, and even Systrace. So this is the tool that you should be using from now on, and this is what these graphs look like. So we have, now, I believe, four graphs. We have the CPU one, the memory one, the network one, and the energy one. I've never used the network one because I'm not sure what servers are for, but I'm sure you guys understand that and you will make good use of it. And that's what it looks like when you enter the CPU profiler. So you get a flame graph. You have different ways of analyzing the data. The one I like is the flame graph. It's going to colorize all the function calls with different colors, depending on how much time they take. So anything that shows in red shades or dark orange are the bottlenecks inside your application. So a very easy way to drill down inside your application and identify the bottlenecks. This is the native profiler. It's available starting on Android 8.0, so you need Oreo or higher to be able to run it. And I mentioned briefly the new memory profiler, so to do memory tracking, we used to use this tool called DDMS. Again, it was a stand alone tool. It was built on the eclipse platform. It was really difficult to use because it was not part of the ID. At some point, we added it back in the ID. And that was pretty much the only good way you could see whether or not you are locating memory in the wrong places. For instance, whether you're doing drawing or whether you're doing layout or touch handling. And now, it's part of, again, Studio. So when you see this graph that shows you, in real time, the memory usage, you can even see the different buckets. So it's going to tell you how much memory you're using on your Java heap, or how much native memory you're using, how much graphics memory you're using. So you can pinpoint where the problem is coming from. You can also create a slice, as you see on screen. It's going to show you all the allocations during that time. You can see the stack traces, you can fold the references. You don't have to dump the edge profile, converted to using edge [INAUDIBLE]. You don't have to run jhat and see these horrible-looking web UI that you used to have to use. It doesn't do everything yet, so sometimes, you still have to go to jhat, but it's a very good way to get started if you have memory issues inside your application. Layout Design used to be like this. It's Article Design. And it's interesting because when Android came out, it was very hard to convince everyone to move to XML. Remember, a lot of angry developers really wanted to write Java code to build the UI. And now, we've given you this. So this is the constraint layout visual editor, and now we have a lot of angry developers who would love to use only XML, and not the visual tool. So I guess we have to invent something new just as a decoy to make you start using this one. CHET HAASE: I think the only constant is that engineers will be unhappy with whatever new option you give them. ROMAIN GUY: Especially if they're French. And if you went to the What's New in Tools talk, you've seen a sneak peek of a new tool for motion layout to create animations using constraint layout. Nicola and John are going to show that again, I think, tomorrow or Thursday. So go find that talk. And so we want to make it clear that this visual designer is only the beginning. There's so much more we can do. We haven't had time to build everything yet. But this new motion layout editor is the next step. And building animations with visual feedback-- real time visual feedback-- is a lot nicer than using XML. Runtime and language, Chet. CHET HAASE: Sure. So Dalvik-- ROMAIN GUY: Don't be so sad. CHET HAASE: Dalvik was awesome for doing what it was designed to do, which was it was optimized for space. When the G1 came out, it had 192 megs, 48 of which-- ROMAIN GUY: Well, 64-- a small portion was accessible for the applications. CHET HAASE: A very small amount of memory was actually available for applications to use, so Dalvik could not, as a runtime, take up a bunch of memory for itself or all the heap and where it needed to store things. So that meant that as devices got better, as memory got larger, it didn't necessarily have the capabilities to optimize in the wholesale way that we needed to. At some point, they basically started from scratch on the Art runtime that, as we said, came out in KitKat and was default in Lollipop. But back in the Dalvik days, we basically had recommendations that came from that because of things like allocations being really expensive. It had to walk the heap and find a place to put this thing, and the heap got fragmented over time, which meant that even if it had a bunch of space there, it didn't necessarily have a lot of contiguous space in which to find a place to put that object. And then collections were also really expensive. You ended up-- you would allocate things over time, and then eventually, it is going to run out of memory. And when it does that-- when you're in the middle of an animation, you're on the UI thread, and it says, I need to allocate space for a bitmap-- can't find the space, better run a GC. You're probably going to lose two or three frames just because Dalvik needed to actually collect all the items without references anymore. So some of the recommendations that we had were basically avoid allocating things whenever you can. That's certainly the way that we live life inside the framework because we are your inner loop, but we also recommended that application developers do that. One of the recommendations that I believe the community has seen batted around was don't use enums, right? Because it turns out an enum structure-- the class structure-- is a whole lot bigger than an int object, right? And we use ints all over the place because we try to minimize the amount of memory we're taking up, and we also try to minimize the amount of time we're creating a new object, as opposed to passing primitive types around. We also said that primitive types are cool. Ints are cool, floats are cool. Capital I integer, not so cool. Also, what's not cool is autoboxing. So when you're using standard collection classes, if you have a bunch of information stored in these primitive types and they're being autoboxed in and out, or if you're using other patterns and approaches that cause these things to get created into objects, you would see, in the tools that we had-- like allocation tracker, at the time-- that you'd be autoboxing and causing allocations along the fly. And then eventually, GC kicks in, and you hate yourself just a little bit more. So modern world, we now have Art. It is optimized for performance. It was created from the ground up not to optimize for memory, but to optimize for performance. And this is performance in terms of method call stuff, but it's also optimized for allocations and collections. Way faster allocations and collections for a few different reasons. One of those is it has it set aside for large objects. So instead of putting everything in the same heap, and then having to find space for large objects amidst all the tiny ones, it puts all the bitmaps in a separate heap, all the large objects, overall. It's way easier to find space for those large objects, and then the small objects go in the separate heap. Also, really cool, it can defragment. Dalvik could not defragment, so it would allocate over time, and eventually, there wasn't enough space for that thing you needed. So you would get these obscure error messages where it said that it couldn't find a megabyte because there's only 48 megabytes free. Doesn't make a lot of sense until you realize, well, it's probably that the heap is fragmented and we can't really do much about that. Now we can. In Art, it defragments the heap. In an earlier release, it would defragment when the application was in the background. Now, it can actually defragment when the application is in the foreground, as well. So way better. So the recommendations that we have now are go ahead and allocate when necessary. It's OK. In fact, if you use enums, I don't care. Go ahead. [CHEERING] Apparently, you do care, so I hope you enjoy them. We still, as a rule, tend to not use them in a lot of framework code and APIs. ROMAIN GUY: I use them. CHET HAASE: They are there sometimes, but as I said, we are still the inner loop. So we tend to be way more conservative than you necessarily need to be in your application code. Use appropriate types. I still think primitive types are really cool, but you know what? If you need to use a collection with an object type, that's OK. But be aware that these phones are still constrained devices. Memory may not be 48 or 64 megs available, but it is still being shared with everything else being used, being run on that system. Also, batteries are really important. It's important to let that battery last as long as possible. So if you're constantly doing things all the time-- if you're constantly generating garbage and collecting it, sure, Art is a lot faster at that. But Art still has to do the work of actually allocating and collecting, and all of that stuff uses power. So it's still good to remember that the battery uses power and that maybe you should be conservative on what you're trying to do. And also, like the framework, be aware of the inner loop bottlenecks. Don't do things in a tight loop that may cause performance problems. ROMAIN GUY: So when Android was started, the team decided to go with the Java programming language to create applications, and there were many reasons for that. The main one was it was an extremely popular language. There were millions of developers who knew how to use this language. There were many excellent and free tools. So it was really helpful for the quick adoption of the Android platform. Over time, we have been, sometimes, a little bit slow at adopting new versions of the language. We recently started supporting the Java programming language version 1.8. I think they are reaching 1.10. But it served us for many years. Last year, thankfully, we announced full support for the Kotlin programming language. How many of you are using it right now? [CHEERING] All right. CHET HAASE: Keep them up. One, two, three, four. ROMAIN GUY: Almost everyone. CHET HAASE: It was definitely more than five. ROMAIN GUY: We'll keep a few slides. So we announced it last year in 2017. We're working in close collaboration with JetBrains. We're making sure that our tools work well with Kotlin, and then make sure that we have access to the features we need. Overall, we like it because it makes code more enjoyable to read and to write, and we spend so much time reading and writing code that it does matter. So I have a few examples here. They're going to be hard to read, but it's OK, because you all know how to write Kotlin. Those examples are taken from the Kotlin extensions, so I'm going to go over them really quickly. I like named parameters. You don't have to create multiple overloads of methods or builders all the time. You can inline functions, which is really useful when you create extensions, or even when you create graphics code, for instance. We saw that. Operators. You can overload operators. You should be careful with that. You can abuse this quite a bit, and I've done this myself. Once, I created an in fix operator called X, because it looks like the cross-product for vectors. Don't do that. It's a terrible idea. I put it on GitHub because it's a terrible idea. You can do destructuring assignment. So when you have a POJO, we create methods called component one, two, three, et cetera. Then you can do multiple assignments in one line of code. So this is an example, again, from Android KTx where we destructure an integer. So you don't have to do shifting and masking of bytes and integers. We have data classes. Very easy way to create all those getters and two string and equals and hashcode. So you don't have to, and you don't even have to type the shortcut to tell IntelliJ to do it for you. That's the level of laziness that we have reached with Kotlin. So that's fantastic. And finally, yes. I just wanted to call out some of the things that, to me, make Kotlin so appealing, is very smart design decisions they've made in language. And one of them, for instance, is when a lambda is the last parameter of a function, they have this special syntax that you can use. You don't have to pass the lambda as a parameter to the function. You can just open the curly braces and put your code right there. It looks and feels a lot more natural. So one of the things we're doing now when we're designing new APIs in the platform-- starting with Android P-- we make sure that our Java APIs are full of these conventions. When we have a single abstract method interface, we make sure that the parameter that uses the interface goes at the end of the list of parameters so that Kotlin developers can benefit from this particular feature in the language. And we're going to do more and more of that in the support library and all of our future APIs. So for those of you who are not using Kotlin yet, a project can contain both Kotlin and Java. You don't have to convert all your application to Kotlin. The next class you add to your application can be Kotlin, or you can convert an existing class. We have a ton of lint checks. If there are things that are missing, go tell Tor. It's going to write it pretty much in front of you and commit it right away. It's kind of a machine when it comes to writing lint checks. Check out the Android extensions. Again, there's a talk by Jake Wharton, I think, on Thursday morning about it. It's going to talk about a lot of interesting things. We also created the style guide. So those of you who are still using our Java guide-- I mean, we didn't really have one, but if you're following our source code, you're probably prefixing your fields with M. You're going to be happy to know that we're not doing that anymore with Kotlin. First, because we don't really like it, and also because you can't really do it because of the property syntax in Kotlin, anyway. We also have an interoperability guide. So if you're going to be writing code that is meant to be consumed by both Java developers and Kotlin developers, [INAUDIBLE] that you're writing Java code or Kotlin code, we have guides for you that explain how you should be writing your APIs so they can be used in a natural manner in both languages. And those are the guides that we are following ourselves for our new APIs in the platform and the support libraries. CHET HAASE: Let's talk about APIs. First of all, layouts in Android, there are a bunch of them, but these are kind of the major ones that people dealt with over time. First of all, there was AbsoluteLayout. And it's so easy to use, why wouldn't you? Then you'd just tell the view exactly where you want it to be, right? LinearLayout, you can just nest those things as deeply as you want to and get exactly the UI you're looking for. FrameLayout, it's fine. If you squint at it, it's kind of like an AbsoluteLayout. ROMAIN GUY: That's the best thing we can say about it. It's fine. CHET HAASE: GridLayout, turns out it's a little bit complicated to use, but we can figure that out, and it has a lot of flexibility there. And RelativeLayout, we've heard that it's expensive. Is this something we should be using or not? So the modern world. Here's how we think about AbsoluteLayout. ROMAIN GUY: We just want to make it clear. [LAUGHTER AND APPLAUSE] CHET HAASE: The only reason that this is not deprecated is because there is one important class the subclass is from-- ROMAIN GUY: No, it is deprecated. It is deprecated. CHET HAASE: It is deprecated. OK. Well, we deprecated it, and that's about as far as we can take it because web view is in AbsoluteLayout. Sorry, don't use that. Hopefully, you're not. LinearLayout, it's actually fine to still use, especially for simple cases. If you're deeply, deeply nesting, then you're deeply, deeply wrong, and there's a better solution. We'll get to it at the bottom of the slide. FrameLayout, it's also OK for simple use cases. You need to put that one thing in there with appropriate padding and margins. That's kind of what it's there for. ROMAIN GUY: And the dirty secret of FrameLayout is that it's an AbsoluteLayout in this case. If you use margins correctly, you basically have an AbsoluteLayout, but don't do that. CHET HAASE: Don't do that. Don't do that. GridLayout-- it turns out that it's really intended to be used with tools, except the problem was we never actually wrote the tools. ROMAIN GUY: I think we forgot. CHET HAASE: Probably not the best layout to use for your situation, unless you already wrapped your head around it. OK. There may be better solutions out there. RelativeLayout-- we believe that ConstraintLayout is, in general, a better solution. I would think of it as a subset of the capabilities of RelativeLayout. It has a lot of the same capabilities of relative positioning of children, with respect to each other. But it has way more relative positioning to guidelines and some of the new capabilities they've been working on in ConstraintLayout. ROMAIN GUY: The way I like to describe it is ConstraintLayout is a RelativeLayout that works. CHET HAASE: And also, the best thing about it is it's tightly integrated with the tool. It was written in tandem by the same people with the tool, which means the design tool works really well with that layout, as opposed to, well, they created the APIs, and the tools sort of never caught up. That is not the case there. We mentioned 2.0. It's not 2.0 yet. I would say it's 2.0 soon. So keep an eye out for what's coming up in 2.0. The talk by John and Nicola this week will go over some of that stuff, probably. Final thought on AbsoluteLayout. ROMAIN GUY: Just to make it clear. So we have a class in the UI toolkit called AdapterView, which is the base class for a number of widgets. So ListView, GridView, and Gallery. And they served us fine for many, many years. They had a few issues. They were difficult to maintain. GridView, I think, has not been used by pretty much any app for quite a while, maybe for applications. Gallery is kind of like a horizontal ListView, and I'm pretty sure it's been deprecated for a long time. And we haven't certainly been looking at it for a while. So I wouldn't use it if I were you, anyway. Probably doesn't work. So here are some of the issues. So an AdapterView has an adapter, and the adapter is interfaced between your data set and the view itself. So one of the things you can do in the adapter is notify the view of any changes in the data set. The problem is that you can only notify it of coarse-grained changes. All you can say is, hey, something has changed. So absurdly enough, in ListView, we have a lot of code that's trying to figure out what has changed. Wouldn't it be nice if you could tell us, because you probably know? Well, we built an API where you cannot tell us. So that's kind of dumb. We also used to tell you to follow this pattern, the View Holder. So the View Holder-- and it's one of those things where I've seen a lot of people mad online about the View Holder because it's a lot of product plates you have to write. It was actually extremely important. I went back and I looked at one of our old talks, and using View Holder pattern would give you an extra 10 frames per second when you were scrolling your ListView on the T-Mobile G1. So it did matter a lot way back then. It's not as necessary anymore. But because of RecyclerView, it's part of the API, so you can now get it for free, anyway. And finally, animations. Animations are possible with AdapterView. So for instance, let's say you have ListView and an item disappeared from the data set. And you'd like the item to fade away, and the rest of the item to collapse and close the gap. You can do this with ListView. All you need to do is write this little bit of code. Chet wrote a blog post about it, I think, a few years ago. [LAUGHTER] CHET HAASE: That was one of the ListView animations. We had a series of videos showing you how to do different ones. ROMAIN GUY: This is part of the code. You only need to understand the future observer and transient state and measures and notes and animations. It was rather difficult. So instead, now, we have the RecyclerView, thankfully. So this is just a dumb application. The first time I actually used the RecyclerView was a couple of months ago. It was so much easier. That was really nice. I was able to create a different version of the RecyclerView. The nice thing about RecyclerView is that instead of having multiple widgets that are effectively different layouts for your data set, you can specify a layout for a single RecyclerView. So this is the same exact code with just different layout managers for the RecyclerView. CHET HAASE: I should point out, too, that all of those were vertical, but you could actually have a horizontal layout. For years, people asked us how to do a horizontal-- ROMAIN GUY: Oh, it's easy. CHET HAASE: Horizontal ListView. ROMAIN GUY: You just set a rotation on the ListView, and then you have to intercept all the touch events and rotate them. And then there's a few more APIs that you probably need to override because-- anyway. That was easy. CHET HAASE: Secret, though. The easiest way is to simply rotate your phone 90 degrees, which has gotten easier with some of the system UI improvements in the latest release. ROMAIN GUY: And one of the nice things about RecyclerView-- it does so many things in much better ways. We have paging and we have prefetching. The API is nicer. You can change layout managers, you can write your own layout manager. But also, animations, they come for free. So the equivalent of the code we just saw is this. And in particular, with RecyclerView, what you get is fine-grained changes. So you can tell us, if an item was removed, what item was removed. When an item was added, what item was added. You can tell us about ranges of items that have changed, or you can tell us that everything has changed. This is much better for you and for us. CHET HAASE: All right. Fragments. In the old days, we heard that fragments were really complicated. And also, we would fix this thing. So we didn't necessarily have everything correct or have all the APIs that people needed, so we would put in improvements, and we would put that into the platform release. And then applications could only use that with devices on that platform release. And so the modern advice is don't use the platform version. We have since ported all of that code to make all of the fixes in the support library, and we have now deprecated fragments in the core platforms. So don't use them there. Use the support library, or now, Jetpack version of fragments. We are putting more goodness there. So use those, and also, we are continuing to make improvements. There's a talk on fragments this week-- ROMAIN GUY: Tomorrow morning. CHET HAASE: --by Adam and Ian tomorrow. So please check that out to hear more information about things that we are doing, as well as ways to use fragments, which should be a little bit easier. A major one of those is the new navigation controller. So check that out. It sort of builds on fragments. It doesn't depend on them. There is no dependency, but it does build on those capabilities for creating and navigating between the screens of your application. Activities are very closely related to fragments. In the old days, basically, Android applications consisted of multiple activities. That was the application flow for all Android applications. We expected developers to do this, and developers did this. When you want to go from one screen of your app to another one, you launch an intent, you get a new window. There, you have some window animation to get you there, and there you are. The new approach is use single activities when you can. It turns out that's a much richer experience for the user. Those window animations-- well, they're animating, but they're not doing anything interesting. They're not doing anything that helps the user transition from one state of the application to another. Instead, it's basically completely separate windows that are coming into view when you could actually use single activity approaches to retain the same Chrome around the application. Might as well have the same action bar with the content switching out from underneath it, or use richer animations, which are possible with either the core platform animations or fragment animations. So go ahead and use an activity. You may have situations in your application where you have different entry points, especially if you have a deep length that someone may come into your application with. Then, it's appropriate to have separate activities. That is the way to expose that information. But otherwise, try to use a single activity. Fragments are not necessary for single activity applications, but they can help with this a lot, especially with some of the recent improvements there and the navigation controller stuff, too. Architecture. So here was the old advice. A few years ago-- OK, only 2016. So basically two years ago, Dianne Hackborn posted this on G+. We usually get this question from application developers, where they will ask us what application architecture they should use in their application. And our answer is always, we don't care. We are not you. We don't know how your application works. We don't know the best architecture for your application, so please make your own decision. And then there is usually a follow-up question of, yeah, I get that. But which architecture should I use? So Dianne posted this to basically say this once and for all. We do not care. The components that we have in there-- the content providers, the activities, the services-- these are system-level components. They're not an architecture around which you build your application. So please build the one that's appropriate for your application. The new advice is, actually, we're happy to provide you some recommended architecture. Because it turns out that people would at least like some common advice that makes sense, and we believe that we have that now. Specifically, with the architecture components, we think that we have an approach that makes a lot of sense. We have APIs that are easy to use and you can build around those. We are not demanding that you use this. Please use the architecture that makes sense to you. But we do have a core architecture that we believe should work. If you're starting a new application, if you have new developers on your team, it makes sense. One of the reasons that we worked with Android architecture components was to solve hard problems. One of the hardest problems was Android lifecycle. And our answer was, all you need to do is understand this diagram and memorize it. And someone, externally, did their own version of that diagram, which looks like this, which is actually a lot easier to understand if you look at it like this. So that's basically everything you need to know and keep in your head at all times. So the problem would be, you would basically create a bunch of methods in your activity so that you could track and manage lifecycle. You're handling creation and starting and stopping and resuming and pausing, and you're probably doing stuff in destroy, as well. You're probably doing too much on Create. You're probably having race conditions, as well as leaks in your start and your stop, and you're probably doing that in the pause and resume, as well. And you're not exactly sure why you're overriding on destroy, but someone told you you probably should. So we'll do that, as well. So in the meantime, you actually only know the lifecycle state if you override those methods. We didn't give you a way to query that. We know what it is, internally. We're just not letting you in on the secret. So there is no API for you to query, so you need to override all those methods, and then you end up chucking too much code in there. So too much logic basically happening everywhere. The new approach is we have an object called the Lifecycle Owner. You can ask for a lifecycle object, and then you can either query the state if you want to know what state of lifecycle you're in, or you can set an observer on it, and then you can get callbacks into those methods. This allows you to abstract it into a separate place so you're not basically bogging down activity code with all this information. But you're putting it where it makes sense in your application. Fortunately, we override-- we subclass lifecycle owner or implement that in both fragment and AppCompat activities. So in the support library, please use these. Those are lifecycle owners. So basically, you can query them to get the lifecycle, and then go from there. So we went from a model where you would have activity with basically all of this lifecycle-dependent logic in it to a model where the activity can be much smaller, take that logic out, abstract it into this other thing over there, set a lifecycle observer on it, and get the callbacks you want. We have a similar problem going on with views and data. We have an activity, and then we have all this information about the views in there. And then we have the data for the views, and we need to know when the data changes, and we need to also track the lifecycle so that we don't leak things or call things at the wrong time. So we just end up having too much stuff there. Well now, you had this concept of a LiveData and a ViewModel where you can put that stuff-- you can abstract it out of the activity. So you can put all that information out there, observe that stuff. So now, in the activity, you should really have only information about views and a reference to the ViewModel. And then put all of that logic in the ViewModel. It's using LiveData objects. It's handling lifecycle on its own, and you can observe it. Way better. Way less buggy. For data, our approach-- our argument to you was you're on your own. We don't manage your data. Do whatever you want. And there are lots of database solutions out there. We have SQLite in the platform. Go ahead and use it. Knock yourself out. Whatever. We don't want to get into that business. The new approach is we actually do offer something for data. It builds on top of SQLite, but it actually offers build time verification, so you're not just sending these queries down and then getting errors at runtime. But you can see this problem at build time and integration with the LiveData stuff that we saw earlier, or you can be on your own if you want to. We're not trying to take over your database solution. We're simply offering a better local persistent story than we had previously, to make it easier for you. The overall diagram looks like this. The only new element here is this idea of repository. It's a pattern for basically abstracting for where the data comes from. So if it comes from local or web, it shouldn't matter to the rest of the people that are querying it. So it's kind of nice to have an abstraction there. Data paging. So we had this thing called CursorAdapter. It had some good elements about it. It did have support for a database cursor. That's nice. But it was specific to ListView, and it had, basically, other problems with inefficiencies-- paging sizes, stuff like that. We had AsyncListUtil, which was more useful, but also was really inefficient for doing things like web transactions. So we have a new model in modern Android. We have data paging. The Paging Library when 1.0 this week, and there are good things about it. So it works with RecyclerView. It handles fine-grained data changes. It's much more efficient, uses background threads very easily. You can observe changes, so it's integrated with LiveData. But again, we're not forcing this architecture on you. If you're using RxJava2, you can integrate with that very easily, as well. And flexible data fetching options, so you can specify the window size and when you want to get these things. There are, of course, always trade-offs. I find that the bad thing about data paging is that the name is rather boring. ROMAIN GUY: Graphics. So when we started Android, we only had OpenGL ES 1.0. We didn't even have shaders. We were doing everything with software rendering. That was an issue for several years. It was fast enough for the early devices. It's only when we hit the tablet form factor that it started to become an issue. We used to do a lot of nine patches, and I'm sure some of you have suffered through the creation of the nine patches, or even worse, trying to explain to your UX designer how to create them. Where do you put the black dots? Which side do they go? I still don't know, to this day. TextureView versus SurfaceView, we touched on that in our preview talk. Basically, there was always this problem of do you use the less efficient TextureView that can integrate better with the other views, like ListView and animations, or do you use SurfaceView? And managing bitmaps was hard. A lot of you built applications, and you were getting out of memory errors because you were trying to create bitmaps and you have to do caching, and this is difficult. And our answer was basically, eh, c'est la vie. So now this. We have OpenGL 3.1 and 3.2. You have content shaders, you have Vulcan if you want to do low-level graphics rendering. We do hardware acceleration everywhere. VectorDrawables have basically replaced most of our drawables and bitmaps in applications. We have small applications. You don't have to support-- supporting multiple densities is a lot easier. You don't need as many batches as before. And something that we're now doing is we're working with you-- very often, application developers turn to us for solutions. But when the community-- that is, you-- have been building amazing libraries that we think are the right answer, that's the ones you should be using. So for instance, Glide or Picasso or Lottie are excellent at what they do. If you want to manage bitmaps or if you want to create crazy, complex animation with Lottie, you should use those. We're not going to spend time recreating something that already exists out there and that we think is very good at what it does. So please go use those libraries. Again, know this. You should probably use SurfaceView, and not TextureView anymore. It has outlived its time. And finally, we used to tell you to profile your code. We used to tell you to avoid work whenever possible and to minimize memory consumption. But now, we have better devices. We have lot of cores, we have a lot of RAM. We have a better language. It's a better runtime. So instead, what you should be doing is profiling your code and avoiding work whenever possible, and also minimizing memory consumption. CHET HAASE: Because it turns out that devices are still constrained. You need to keep that in mind. Battery life is critical and bandwidth is precious, and all of these contribute to user experience. So your user will thank you if you are actually still being conservative about these things and getting the best performance for your application that's appropriate. We would like to thank you, and there is a different way to say this. And I think we're done. Thank you. [APPLAUSE] [MUSIC PLAYING]
Info
Channel: Android Developers
Views: 118,960
Rating: 4.9246821 out of 5
Keywords: android developers, whats new in android, Android P, Kotlin, android devs, android io announcements, new in android, new in android 2018, 2018 android updates, android jetpack, Google I/O 2018, Google I/O, Google IO, I/O, io18, io 18, #io18, IO, google livestream, IO Google, google products, google platforms, web development news, android developer news, developer update, Google conference, google I o, developer news, developer event, google, developers, google developers
Id: IrMw7MEgADk
Channel Id: undefined
Length: 39min 17sec (2357 seconds)
Published: Tue May 08 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.