What's new in Android Studio (Android Dev Summit '19)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[MUSIC PLAYING] JAMAL EASON: Welcome to our session on what's new in Android Studio. My name's Jamal, and I have with me Tor today. Today, we're going to talk about all the latest new features inside of Android Studio, plus take a deep dive on some things you heard about during the Android Developer Summit keynote. As a framework for our session today, we'll talk about features that are available in stable today, all the way to the bleeding edge features you'll find in the Canary channel. All right. To get us up to speed, let's take a quick step back. At Google I/O, we launched Android Studio 3.5 into beta. There, we focused on system health, feature polish, and our bug backlog. Just this past month, we launched Android Studio 3.6 into the beta channel. That had things like [INAUDIBLE] support, emulator with integrated Google Maps, design tools improvements, and Kotlin and JNI support. And today, we're excited to talk a little bit more about Android Studio 4.0. OK. With this context, let's talk about what's inside of our stable channel today. To recap, Android Studio 3.5 focuses on three main pillars-- system health, feature polish, and our bug backlog. Now, that all culminated in something we called Project Marble. Now, specifically, Project Marble included a number of smaller projects that our team worked on across the board. Things like crashes, improvements to apply changes, hangs, CPU usage for the emulator, R8 improvements, and our bug backlog. Now, I want to talk about some of the improvements, but also the successes of Project Marble for your awareness. OK. One of the first issues we talked about and worked on was around hangs and latency. For this specific example on the screen, we looked at XML typing and data binding. And what we found is there are some critical bottlenecks we had in typing. So we analyzed and improve those things. We did that not only for XML. We did that for Java and the Kotlin programming languages as well. Another pain point we heard from you is about memory. And the symptom of this is that, hey, the ID is slow and not responsive. And the root cause of that is actually the memory issues itself. So the first thing we did is actually create a new set of infrastructure and dashboards to catch these issues as we checked in code into Android Studio. And of course, we can't catch everything, so then we added a new set of client side analysis for you. So if you notice if Android Studio is slower and sluggish, you can now create your own heap dump and have a sanitized version of heap dump that you can share with us, so we can understand what's going on with your machine and how to best solve those problems. Then lastly, we heard a lot of people complain about sort of the overall speed of Android Studio. What we found from the opt-in data is that a lot of people were using the default settings of Android Studio. Well, this is fine for interim projects and beginning projects, but as your project expands and you add more functionality, you can actually increase your heap size for better performance. So if you ever see this pop up-- many come up in the bottom right-hand corner of Android Studio-- please look at that and accept those settings. We've actually applied some analysis and some models to understand how to best configure your Android Studio and your Gradle plugin to have better performance. So speaking of the build speeds, we spent a lot of time during Project Marble to look at how to improve build speeds. So before Project Marble, we had about a 12.5-second average build speed. And we've drilled that down to about 9.5 seconds post-Project Marble. Digging in a little bit into the data you saw this morning, specifically, we're actually working on build speeds along the way, from 3.0 all the way to 3.3. What was happening, we noticed, is that projects are just becoming more complex. Either if you added annotation processors or more features to your build speeds, it was just slowing down and you weren't able to keep up. So in the 3.3, 3.4 time frame, we now were able to stabilize that. And what we're excited about is, with Android Studio Gradle plugin 3.5, we actually have seen a decrease in build speeds. So if you haven't moved to Android Studio Gradle plugin 3.5, I highly encourage it to take advantage of all the major improvements for build speed. And the last we looked at for us is on deployment speed. So deployment speed is the time it takes for you to make a change on Android Studio and see it on a running device or an emulator. So the medium before that, before Project Marble, was about 7.9 seconds, and we drove that down to about 3.6 seconds. And that was all around the feature called Apply Changes. And Apply Changes, if you don't know, is a replacement to Instant Run. And Apply Changes is a fast, iterative way to make changes to your application. So if you haven't been using Apply Changes, I highly encourage you to use that as well because that will dramatically improve your incremental change and workflow in developing with your app in Android Studio. All right. So recap, we've done a number of improvements for Project Marble and we're really excited about those things. And thank you to all of you who filed bugs and shared with us opt-in data. Without that information, we wouldn't know what to prioritize to make things better for your development. But quality is definitely not done. We set a new quality bar for ourselves that we want to maintain going forward. So with this quality bar set forward for ourselves, we want to continue working on new features for Android Studio. So today, we're going to give you a preview of a lot of the new things we're working on inside of Android Studio. But before we migrate those features from Canary to stable, we're going to prioritize and assess those features and match them to the quality bar that we set during Project Marble. So instead of talking about all those cool features we added to Android Studio, I'm going to have Tor walk us through some of the cool things that we have inside of Android Studio. TOR NORBYE: All right. Thank you, Jamal. So one thing we hear over and over again is that you want your builds to run faster. And as you just saw, we've been making some good progress. But as you'll see shortly, just speeding up the Android plugin is only part of the puzzle. So when you want to write your apps and make them faster, you run a profiler, right? Well, what we've been working on is a profiler for your builds. So I'm going to show you what that looks like. So this is the Santa Tracker Project with some deliberate build mistakes I've added in. And after you've built now, you get this new build speed task, one for each build that you run. And this gives me a breakdown into what happened during the build. So for example, here, I have a breakdown of all the tasks that determined the build duration. Right? So this is showing me the tasks are on the critical path. There's no point in trying to optimize a task that is not on the critical path. You make it faster, you're still waiting for a longer task. Right? We also give you a breakdown of the build time for each plugin. So you can see here, I have a plugin that's taking up 40% of this build. This happens to be a third party license plugin, so what it's doing is very valuable. It's fetching license files over the network and inserting it into the Help menu. But maybe, I don't need to do that on every single full debug build, right? So I can maybe investigate and get into release builds. So this gives me an insight that I can then go and do something about. We also tried to surface a bunch of problems in the build. So for example, always run tasks. Tasks should only run when their inputs have changed, but as you can see, these tasks are not actually declaring their inputs. And that means they're going to have to run every single time. So if this is your task, then you know you should fix it. Otherwise, you should contact the author and ask them to fix it. Another problem that we pinpoint for you here is task setup issues. So if you configure multiple tasks to share the same output directory, then they can't run incrementally. So if you do that, you're breaking incremental compilation, and again, we're surfacing that to you right here, listing the tasks that are conflicting. Non-cacheable tasks. This is pretty important if you want to use the distributed cache. These are not going to work. And then, of course, non-incremental annotation processors. So if you use an annotation processor that's not incremental-aware, it'll force a full rebuild. And they all have to be incremental-aware. Now, we've been working on a lot of them and working with annotation processor authors to actually update to Gradle support for incremental APIs, and so in some cases, it's as easy for you as updating to the latest version. So when we know, for example, here, we're telling you auto-value, switch to version 1.6.4 and your build will run faster. And then there's configuration time. So configuration is where tasks are created, whether or not they're going to run. This is supposed to be a very fast operation. But some plugins will actually do a lot of computation during configuration. I've actually created a slow one here that waits for two seconds. It's simulating, doing lots of computation that you shouldn't, but this gives you a chance to sort of dig in and see exactly what's going wrong. So as I mentioned, you get one Build Speed tab each time you invoke the build. So I did a full build here for about three minutes, two, three minutes. I then did an incremental build. So now, I can see the breakdown of what happens in my incremental build. You can see the licensing is no longer the issue here. And so, by breaking this up for each build, you can decide whether you want to optimize for CI, the full build scenario, or if you want to optimize for your incremental build in the IDE or preferably both. But you're probably going to have more value out of the incremental builds as you do those over and over and over again. So that's the new build attribution feature that we have in 4.0. It's not actually in Canary 1, but hopefully, we will land it soon. All right. So while we're on the topic of Gradle, we now support the Kotlin Gradle DSL. So that means that you can write your build files in Kotlin. And that's really good for the IDE because we can reason about Kotlin. It's statically typed, so the editor support is better. And so, for example, code completion now, if you've ever wondered what you're allowed to configure inside default config, well, wonder no more. You can see the exact list here. Similarly, lint options. If you want to know what you can invoke and what you can customize, they're listed here. And you can also pull up docs for the DSL, which is pretty handy, right from the IDE. [APPLAUSE] We also run lint on your KKS files. And in 4.0, the biggest amount of work for us was to implement the ability to read, analyze, and write these build files. So the product structure dialog now also handles Kotlin DSL. So I can go in here and I can accept these suggestions to update to the latest version of these libraries, for example. And then hit Update, and then it's going to rewrite the build file and run another sync. OK. Let's see. Let's go to number two. So let's take a look at the Compile Options section. You'll see this new flag here called coreLibraryDesugaringEnabled. So this is for a new feature in 4.0 called library desugaring, and this lets you access APIs that normally require a higher API level on an older API level. What we do is we rewrite those calls into a backboard library that we bundle with your app. So let's take a look at what that looks like. So here, I'm using Java.util.stream, lint tells me that this is going to crash prior to API level 24 so you can't use it. Right? Well, now, if you turn on library desugaring-- it's actually complaining in this module because this code isn't in the module where I turn on library desugaring, but if I switch to the same code in my library desugaring module, you can see lint is happy because this is going to work. And let me show you the bytecode to see how this works. So this is the same method I just showed you, and if we look at the bytecode, you can see that java.util.stream has been replaced with this j$util.stream. That's basically the backboard library. And it's good to be aware of this because you might see these package names in stack traces and debugger and so on. And note that this is not limited to java.util.stream. You can use this for java.time. You can use it for java.util.function, java.util.optional, and we even rewrite references to concurrent hash map. Because it turns out that, on some devices, concurrent hash map has a really bad bug. And so by using this feature, we will just replace your concurrent hash map usages with the safe one and you won't be bit by that bug. All right. Speaking of decks and [INAUDIBLE] and R8s, for code shrinking, we still use ProGuard files to drive the process. And so in 4.0, we've improved our support for ProGuard files. We have better code completion, we have go-to declarations, and the most important part is that it is now find usages and refactoring aware. So if I, for example, rename this class that happened to be referenced from a ProGuard file and I apply that refactoring, you can see that the ProGuard file is also updated. So no more stale ProGuard files after this. [APPLAUSE] All right. So back to our Gradle file again. I've also turned on view binding. So view binding is very much like data binding, but it is easier to use and it has a smaller impact on your build speed. So once you turn this on, it'll create a binding class for each one of your layouts. So here's a class that first does things the classic way, right? So we have a set content view, we'll be passing in a layout resource, then we fish around in the view hierarchy with these find methods. We apply a cast that'll hopefully work, and then we take our chances accessing that object. With view binding, what we do instead is we access or inflate the layout with this generated binding class. And now, we get this binding instance which knows exactly which views are present in the layout. So in this case, text view is present in all versions of activity main. So that means that we know it's non-nullable and it's safe to access. I will have no null pointer exceptions with this one. View binding knows that button is actually missing from one of the layouts. So it's marked as nullable. And if I hadn't used the elvis operator here, Kotlin would have refused to compile. So view binding is great for catching nullness, and it's also pretty good performance. All right. So view binding makes it really easy to access and update your views, but we're working on a brand new framework to make it even more powerful and easy. And that's Jetpack Compose. So this is Hello World from Compose. So what we do here is we can take an existing composable, or a widget, and we can wrap it in our own function and customize it with some arguments. And as soon as we put a composable annotation on it, voila, we've created our own widget. And we can also market with this preview annotation. And then it shows up in a preview pane inside the Kotlin file. This is a bit like our sample data support in the old Layout Editor, but now applied for Compose. And so we've created our own widget called Greeting here. We can take that further and we can throw a for-loop around it and other conditionals. And we can wrap it inside another composable. So you compose new widgets by adding composables. So the name makes a lot of sense. So we had the preview again, and note that this preview is not limited to one. So here, I have a button widget that I've created. It has two states, on and off. And notice how I can preview all the states, including in dark mode as well, which is pretty handy. And here's an even more complex example from our Newsreader app. So this is a card we used to show available stories. And here, you can see we're also showing you, for example, what this looks like with a larger system font. So the embedded preview is really great for tweaking your views as well as seeing what they'll look like across different dimensions like theme and font size and things like that. But sometimes, you really want to run the app to modify the behavior. And so I'm very excited about this next feature. If you watched the keynote, you've already seen it, but I'm still excited about it. This is a feature I've wanted since before Studio 1.0 but it was very technically challenging, but the team is in the process of pulling it off. And that is, of course, the ability to have the emulator embedded inside the IDE. Yeah, I love this. [APPLAUSE] So this is the real emulator, right? It's not just simulating the app in isolation. I can install accounts, I can launch intents and all that. And what's nice about having it inside the IDE is that it participates in window management, right? So if I'm the source editor and I want to focus, I press a key binding, I'm in my editor, and I can bring it back very easily. So it's super convenient. So this is my Compose app running. We can drill into it here. And let's click on the Bookmark icon. And when I do that, I'm launching an attempt and that's actually not what I wanted to do. So I've introduced a bug in the app. So let's just go and fix that. So I'll jump to the related code. This is the toggle bookmark code. Oh yeah, I had a to-do here and a stopship marker, too. Let's try Apply Changes. And it's now reloaded the app, and I can invoke the bookmark and it works. So this combination is pretty productive right here, running in the IDE. One last thing I'll mention about our Compose support is we're working pretty hard on making the editor experience better, right? So for code completion, for example, we are ranking composables to the top. Notice that we're also-- normally, you'll have types on the right, but we are removing types from the right so we have more space to show you all the parameters. We're hiding defaults. And we also have a special code completion insert handler. So if I, for example, insert a row, if I don't enter anything as a parameter and I hit Enter, we remove the parameter list, and so on. So we're trying to make this editor really smooth as you're working on Compose. OK. We're also working on the classic view system. So let me switch over to the Layout Editor. It's the Sunflower app. So here's an XML file. Now, do you remember how, in the Compose file, we included the previewer right there in the source editor? We've done the same thing for layout XML files. We used to have a separate tool window, and in the Layout Editor, we had Design and Source tabs. What we're doing now is, instead, we have these three buttons at the top. This works in Compose. It works in the Layout Editor. And you can use key bindings to quickly map between them. So if I press Control-Shift-Left here, I'm in pure source. If I go to the middle one, I can have them side by side. And if I go all the way to the right, I have the full Layout Editor. And this also works for custom views. So here, I have an Android custom view, and I now, within the Java or Kotlin editor, I can see my custom view. When I'm tweaking the [INAUDIBLE] code, it's right there. And it makes it a lot easier to work with. [APPLAUSE] Right. So let's look at the Layout Inspector. So I'm going to run this app again. Open up the emulator. All right. So this is the Layout Inspector. And actually, that's not. That's the app running. This is the Layout Inspector. And it's going to attach to my running app. See, OK, it's already connecting. So what it's doing now, it's going to pull down the whole view hierarchy. There it is. Let's give ourselves some more space. So the first thing I can do here is I can click on various views and I can see their values. We had that in the old Layout Inspector. But what's new is this Declared Attributes section. So here, you can see resources that are coming from binary resources or XML resources. So let's take a look at the label, Add Plant. Where's that coming from? Well, I can expand that and I can see that it was actually specified right there in the Layout file. And I can continue with the whole resolution stack and see the exact line and language that it came from. And normally, it's not difficult to find where a string came from. You can just search for it. But what about colors? So you can see that this button has a green color. Where's is that coming from? And again, I can expand and you can see we have multiple alternatives here. And it's probably too small for you to see. I mean, I can barely see it from here. But there's strikethrough on all the theme references for material where this color would normally be specified as gray. Instead, we have some other attributes that have a higher priority that are winning, so I can see that the real green is coming from this local layout reference to a theme attribute, which again, we can chase down the values for. So this is a bit like the Chrome DevTools, where you can sort of investigate the whole resolution to figure out why, oh why is this text, whatever font or color you're concerned about. One other thing to point out is that this inspector is not just a static dump of the view hierarchy. It is optionally live. So if I go up, and in my running emulator, click, for example, on the Plant list, you can see that it's now going to fetch all the surfaces and stay up to date. So I can continue to see what's happening in the app. And one really nice thing about that is that I can now drag this in 3D and see the full view stack here. [APPLAUSE] And the really useful thing is, look, we have a full texture sitting back here. And notice how we're showing textures that are hidden, right? So this is not just a screen grab from the device. We're getting all the surfaces because this is running on Android 10. So we had to actually add some support to do the value tracking and this bitmap fetching. But now, we can see that we have this texture hidden by the screen. So this is overdraw, this is bad, and this tool makes it easy to track down those kinds of bugs as well as issues with clipping. So that's the Layout Inspector. All right. Let's talk about the Motion Editor. All right. So here, I've created a very simple constraint layout. And what I want to do is I want to animate this so that it's a bit more lively when this layout shows up. So what I do is I open up Convert to Motion Layout. This will migrate my layout into a motion layout, plus create a scene file that's going to store all the key frames that we're about to create. So the first thing I can do is to select the start state. So we have start and end, right? I'll select a start state, and then I'll start changing some of the constraints in the scene here. So I'm going to be deleting this to move the text to the top. Let's also attach this button to the bottom. And now, we've already created ourselves an animation. So if I switch to the transition view and I hit play, you can see it's now going to start animating this. And we can go ahead and turn on showing paths so you can sort of see these lines here showing how these widgets are going to move. So the next thing I can do is I can try to make this motion a bit more interesting. So I don't want a linear path for the label. So I'm going to now add a key frame, a position-based key frame, on the text view. And I'm going to have the type be relative to parent. And let's move it about 100%. I just learned, by the way, that in Android, we use one-based percent, which doesn't make a lot of sense. All right. So you can see now that the motion is a little bit more interesting, right? We can also fade in the button from the bottom. So what I do then is I add a key frame based on an attribute. So we'll pick the alpha and we'll put this on the button. So now, this is going to fade in from about 0.5, and we can change that to be-- let's start from completely transparent instead. So now, this button is going to fade in. And let's add some rotations because I like rotations. So another key attribute. And this time, we're going to be rotating the text view. So rotation on alpha. It starts out at 45 degrees. I like to give it a bit more spin because rotations are cool. So let's do 145. And we should also move it off screen so it doesn't start in the middle. And so to do that, I will first select the States, Text View, and then we'll add bottom padding here. Let's say 300 or so. All right, let's see how this is starting to look. So when I play, OK, we got some motion. [APPLAUSE] Yeah. So you can see that you can really go overboard. Do you remember the web in the old days with the spinning logos on the web page? Yeah. Don't go too far. But with some tasteful design, you can really accomplish a lot with this tool. So let me switch to a slightly more complex layout. So what you see here is just start and end states, right? Well, that's just the default. You can also create many other states. So here, I have a base state. This is just a bunch of cards laid out with different colors. I have this other state where all the cards are on top of each other, and then there's a third state where they're all sort of off screen up to the left. And now you can sort of sequence the transition between all these different states exactly how you want them. So we can have this transition. We can have this transition. We can have-- let's see. I chose a state. We can have this transition. And let's check out the translation curves down here, too. So you can do really advanced things with this tool. The last thing I want to highlight is that you can easily also create click and swipe handlers. So when you do that, Motion Layout is going to add the code for you to basically add listeners. So if I had a swipe handler, for example, the user can swipe and then Motion Layout will scrub through the animation, a bit like the Quick Settings pull-down on Android. You can do this through the tool, which is pretty fantastic. There is so much to show here that I don't have time to get into. But the good news is, if you stay in your seats for two or three more hours, there's a whole talk from the Design Tools team that are going to show you through all the goodies that I couldn't show you today. All right. So a couple more quick things to show you. First of all, in the Resource Manager, we've updated the Vector Asset Wizard with brand new clipart. So the Materials Design website has many icons. We've added them. More importantly, we now support all the different types. So you can switch from, for example, filled icons to outline icons to even the two-tone icons. So hopefully, you'll find that useful. Another thing we recently did for editing is we ported all of our Android live templates to Kotlin. So if I, for example, want to add a logging tag into this class, I just type logt, hit Tab. This will create a logging tag for me based on the current file name. Right? And more importantly, or more awesomely, if you ask me, logm. This one will basically log the current method name with all the parameters. Right? [APPLAUSE] And if you want a block structuring comment in between SPC tab, you can type in your comment, whatever. So what you want to do is open up the Live Templates UI, Live Templates Settings, and browse through all of these to learn what tags you can type in with tab. It'll save you a lot of time, I think. All right. Next, I'm going to show you some stuff in the emulator. So look, still also runs standalone. So if I pull up the options, Android now supports multiple displays. And so we've made it really easy to test multiple displays in the emulator. All I have to do is go in and add additional displays. I can tweak what kinds of density I want. So it's suggesting this layout right here. If I hit Apply Changes now, you can see I have my emulator connected to multiple displays that I can then start interacting with. Yeah. So definitely give that a try. All right. We've also made it easier to test locations. So let's say I want to test motion. Let's say I have some sort of fitness app or whatever. What it can do is say, I want to navigate to the Googleplex. And I'm going to start from where we are right now, which is Google Building MP7, I think. I can now save this as a route. I'll call it Demo. Save. And now, I can play this route. And let's see what happens if I go into Google Maps here on my emulator. If I click the Where Am I icon, it's now supposed to be showing us that we're moving. And we are. [APPLAUSE] All right. Unless I forgot something, I think that's my demo. So now, I'm going to turn it back over to Jamal, and I hope you enjoy Studio 4.0. [APPLAUSE] JAMAL EASON: All right, so some really cool demos. Unfortunately, we don't have time to demo everything, so I'll spend a few moments talking about some additional features we're launching inside of Android Studio. So first, we're updating dynamic features. So as you know, today, with dynamic features, I can have a module feature connected to the main module. What we're updating is that now, you can have feature to feature dependency. So let's say I have a camera module and I want to add a video module to that. So now, I have a direct dependency to the camera module without having a direct dependency on the app module. So that's a cool feature we've added for dynamic features. Another thing that we added behind the scenes is actually improvements to the Layer Editor. So actually, what we did, we took the rendering libraries that we have on the devices and put them directly in the IDE. So things like Skia and ICU are now available inside of Android Studio. And what that enables is two important things. One is the performance. So all the demos you saw Tor using with reactive performance, that's there. And two, having higher fidelity accuracy. So specifically, things like improving text justification mode is now supported. Having detailed shadows or having 3D perspective. Or having text path rendering are now available inside the Layout Editor. So this is all happening behind the scenes and helping you have a better experience inside of Android Studio. Just as a quick update, we also did a big pass update on our templates for fragments. So we have a new wizard that's there. We updated all the templates for fragments. So if you use fragments, check that out as well inside of Android Studio. Now, a big update for the Android Emulator is something we're calling kind of this dual ARM x86 support. So let's say, if you have any C++ code today that had ARM support only, you weren't able to use the x86 emulator because that didn't support the fast experience. And so today, we have a special version of the emulator that supports both ARM APIs and x86. So it can run that Legacy or C++ code on one emulator and have that fast x86 experience. So we just released this on one version, and we're really looking for your early feedback to make sure we have all the right use cases. And we'll scale this out as you add more features to this going forward. And I also have an update on Chrome OS. So at I/O, we talked about having full first-class support for Chrome OS for Android Studio. And one pain point for that is that, if you wanted to debug your app or deploy your app, it required you to have an external Android device or boots your Chrome OS device into the developer mode. Now, that's no longer needed. You can do all your end-to-end development right inside of your Chrome OS device. So with the updating release of M80 of Chrome OS, you can now do your development, debugging, and deploy the app right directly into Chrome OS to see it running inside of the Chrome OS laptop. [APPLAUSE] OK. So we talked about a range of features that we're releasing. Things in the stable channel and also things on the bleeding edge features on the Canary release channel. Now, let me talk about the Canary release channel. Of course, it is bleeding edge, right? A lot of things are just in development and we're trying to explore things that are going on. And to that end, it's actually very lightly tested. So we do recommend running both stable version of Android Studio and the Canary version of Android Studio. And you can do that as long as you have your Gradle plugin tagged with the stable version of Android Studio. You can run both in parallel on the same project with no issues. TOR NORBYE: But for build attribution, you'll need 4.0. JAMAL EASON: Yes. [INAUDIBLE] But as far as feedback goes, we do encourage you to use Canary because it's the best feedback channel for us. If you file a issue or a bug on stable, it's a little too late for us before we moved onto the next version. So if you like the features you saw today and want to give us feedback, please use the Canary channel for that feedback mechanism. But even more importantly for us, we're actually very quality-driven. Going back to my earlier point about Project Marble, we set a new bar for ourselves for quality. So some of the things you might see in Canary may not make it into the initial version of stable because it may not be ready. And that's OK because we want to make sure it's stable and has a high-quality release before we make it available to you in the stable release version. OK. So we talked about a range of things today, and thinking about a recap, we talked about some things that are actually in Android Studio 3.6, things like the multi-display mode, Design Tools updates, and the Intellij update for 2019.2. And then things like the Jetpack Compose and Motion Editor support, those are inside of Android Studio 4.0, which is currently available in Canary. So please check those out as you're trying out Android Studio. And with that, please download Android Studio Canary to try these features out. Again, I'm Jamal and this is Tor, and thanks for coming to our session. [APPLAUSE] [MUSIC PLAYING]
Info
Channel: Android Developers
Views: 47,667
Rating: 4.874126 out of 5
Keywords: type: Conference Talk (Full production);, pr_pr: Android, purpose: Educate
Id: XPMrnR1_Biw
Channel Id: undefined
Length: 34min 53sec (2093 seconds)
Published: Wed Oct 23 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.