Uncategorized

[MUSIC PLAYING] ROMAIN GUY: Good morning, and welcome to What’s New in Jetpack in Compose I don’t know why it’s called that, because this is not really what the talk is about It’s more, what is Jetpack Compose? Anyway, I’m Romain Guy I manage the Android Toolkit team at Google CLARA BAYARRI: I’m Clara Bayarri I’m a tech lead on the toolkit ADAM POWELL: And I’m Adam Powell And I am also a tech lead on the toolkit ROMAIN GUY: And the toolkit now is also Jetpack Compose My clicker I need that All right So what is Jetpack Compose? The real title So according to developer.android.com, Jetpack Compose is a modern toolkit for building native Android UIs And it simplifies and accelerates UI development Blah, blah, blah It’s all in Kotlin So instead of trying to tell you what it is, I think it’s more useful if we try to tell you what kind of problems we’re trying to solve, what kind of goals we’re trying to achieve with Jetpack Compose We did some of that And look, it’s me again Same short Same pants Different watch ADAM POWELL: Consistency It’s good ROMAIN GUY: Yes So Adam and Jim were with me on stage and did most of the talking So we explained some of the reasoning And I wanted to go over other points The first one for us is to simplify the development And we all got used to the complexity of Android development And the complexity can mean many different things Some of our APIs already are awkward to use You have two many different files, different languages So I want to show you an actual example So that’s something that Jim, who works on the Compose compiler in runtime, has come up with to try to convince a bunch of people internally that Compose is a good thing So the idea is to build a simple app where you have a list of names And you just want to type something at the top And it’s going to filter the list So how would you do that with the existing UI toolkit? You start with the simple XML file You’re all used to that, a recycler view with the text and the [INAUDIBLE],, all that good stuff Then you need another XML file for each list item in the list So we already have a couple files in XML Then you need your filtered list view that’s just going to do that find [INAUDIBLE],, find delete text, set up the listeners, find the recycler view, set up the adapter I’m not even showing the activity here Finally, you need the adapter itself So actually, it’s funny Because when I put that on the slide, I’m like, wait, is that the best way we have to filter a list? So I Googled it And it turns out– [LAUGHTER] Because I did write some of the filtering APIs So I thought there was a better way It turns out there’s not really And there’s a lot of blog posts, articles, and even Stack Overflow questions on how to do this I’m proud to announce that this is one of the simpler ways And then you can use RxJava or fancy frameworks to make this happen Anyway, that’s a lot of code It’s annoying It is not simple So this is the entire Compose version All the code you need is there on screen Much easier It’s going to be a lot easier to find bugs And more importantly, when you read the code, it’s pretty obvious what the intent of the code is, whoever read that code, what they wanted to do So you say, I want a scroller I want a column of text fields Sorry I want a column with a text field at the top And for you each row I want an imagined piece of text And as soon as you change the content of the list to contact list, everything updates as you would expect Another thing we want to do is fix what’s broken So that’s our API regrets We talked about this at Google I/O I invite you to watch the talk if you want to know more We had a few funny anecdotes One of the good ones, of course, is View.Java that now clocks at around 30,000 lines of code Sure There’s a lot of comments in there, but still– ADAM POWELL: I think that’s down from some point ROMAIN GUY: Yeah But still, it’s a lot So the plan for us is also we have a lot of baggage and history So there are things that we just cannot fix We know there are problems, but we just can’t fix them We could introduce new bugs, or apps may be relying on the current behavior So we’re kind of stuck We can’t really do much more with the existing UI toolkit We want to stop cheating This is something we did originally And I think Adam recently, you said on the Kotlin [INAUDIBLE] Slack channel that you really, really want add hide to disappear So if you ever looked at the source code of the Android platform, we have this magical annotation called add hide, which turns public APIs into very private APIs And super useful to us It was a way to work around some of the limitations of the Java programming language But it led, over the years, to an issue for us For instance, let’s say you want to do something with text view That text view doesn’t do well out of the box So you have your sensors Write your own text view Well, you start pulling that thread And then you’re grabbing the entire text package And you’re running two priority APIs all over the place, and you can’t do anything about it So that’s an issue for us And it’s an issue for us So what we want to do with Compose is we don’t want to rely on private APIs anymore We kind of have to at the low level to interact with the platform But all of our widgets are built entirely using public APIs that are available to you And I’m going to show you actually an example of that ADAM POWELL: And the good news is that it’s kind of forming a forcing function for us to open more things in the platform itself along the way ROMAIN GUY: And we have to think a little harder about what we open Material and animations Oh, I had a pretty heart emoji on the slide It’s gone ADAM POWELL: Aw

ROMAIN GUY: I like hearts Anyway, so now we’re in the Material Design world The existing UI toolkit was built before Material Design was a thing So the good news now, we can take Material Design into account This is what Clara and her team do in London And we also are building animations in strong collaboration with the rest of the Compose UI toolkit So we expect it’s going to be easier and more powerful than it was in the existing one Tools plus Compose Same thing When we built the initial UI toolkit, the existing one, there was not that much interaction with the tools team because the tools team was very small So a lot of the tools came after the fact So the visual editor, the [INAUDIBLE] that you saw in the keynote And we want to change that And you just saw that we’re building things like live previews that are composable right now, as we’re building Compose itself We adopted Kotlin We announced that we want to go Kotlin first So that would be one thing for us to tell you to go Kotlin first And we thought that maybe it was a good idea to do what we say that you should do So Compose is returning to Kotlin And Kotlin actually unlocks a lot of the things that we do in Compose The way that we design the API is possible thanks to Kotlin We rely heavily on lambdas, for instance And we plan on using fun features like co-routines Adam is chomping at the bits to add co-routines all over Compose And finally, compatibility is something that we deeply care about We are not asking you to rewrite your entire app If you want to adopt Compose, once it’s ready for production, we don’t expect you to just delete all the code, like we did for Instant Run and to start from scratch We want you to write your next activity, or your next fragment, or to be able to reuse some of your custom views And chances are that some of the existing views, we won’t even rewrite ourselves So things like surface view or web view If any of you wants to write a new web view, please come help us But we’re not going to do that So we’re going to use the existing [INAUDIBLE] All right And finally, this is what the technical stack of Compose looks like So on the one side, we have the build time stack So that’s on the host that runs on your machine So we use a slightly modified version of the Kotlin compiler So we work closely with JetBrains We just added a couple compiler extensions in collaboration with them And we use those extensions to enable our Compose compiler plugin So it’s funny, because last week people saw that we had the artifacts on Maven for Compose And people started using them And they’re like, oh, great It works We’re like, no, it doesn’t work You need the compiler that we haven’t released yet Like no, it works The reason it seems to work is because the syntax is just pure Kotlin So it’s just invoking functions It was just not very reactive at all, which is kind of a bummer Anyway, and so we also have Android Studio And then on the runtime side, so Compose at the bottom is a runtime that just deals with trees It knows how to produce trees It doesn’t know anything but UI toolkit So we could reuse it to do other things than UI Then we have the UI core, the UI foundations, and, finally, on top, all the widgets So that’s pretty much it And now Clara will tell you more about how Compose actually works when you write code CLARA BAYARRI: Thank you [APPLAUSE] Sorry Get your applause I want to walk you through some of the things that you need to understand to really be able to play with Compose, some of the basic concepts The first one is composable functions I know Romain has kind of thrown this term out a few times But a composable function is just a function It’s a function that takes some input, and just decides what UI to show based on that input So in a way it transforms your application data into your UI hierarchy Creating a composable function is very, very easy So, for example, we have this greeting composable It takes a name as a string And it just decides to emit a text element that uses that string Text is one of the components that we will provide for you It is the equivalent of a text view So it shows a text on the screen The interesting thing here is because we have the runtime and the compiler behind us, whenever you change that input– so say the name you’re going to pass through changes– well, then we take care of figuring out what changed, re-invoke the function, and figure out what we need to change in the UI hierarchy for you so at any point you are just describing what you want to see And we’ll take care of the rest Say, for example, we want to build a news story We can actually omit several composables within a composable function So we can omit, say, a title, subtitle, and a date And we’re just going to build our news story This is absolutely fine But you will find you kind of need to have an opinion on how you want your UI to show Because if you just do this, you will end up with something like this, which is not really what you wanted So this is where concept number two, layouts, come in We are building out a bunch of layouts for you out of the box to make sure that you can place things on screen as much as you want So, for example, we can wrap those three texts in a column Column is the equivalent of a vertical linear layout So we’ll just place everything one on top of the other So then suddenly this looks more like what we were expecting Right? So we have our title, subtitle, and date Still, Android developers are used to being able to customize a lot of things You’ll be like, ah, you know, this is nice, but my text is really stuck to the side of the screen So we can go a bit further, add some spacing And what that will do is just create the spacing around it that we need to make it look a bit better So until now, we’ve built this entire UI

just as like one function Right? Going a bit further, column doesn’t just take text I know I used three text as an example But we can throw anything in there So, for example, we can just display an image by using an image composable, and then build up our UI in this way Huh Oh, yes Sorry We’re providing a bunch of layouts out of the box There you go We have row, which will place things horizontally We have column, which will place things vertically Those are easy to understand We have more advanced things For example, we’ve introduced flex, which I believe is new to Android We’re building a bunch more There’s a bunch more in there that you can go and play with And we are working on ConstraintLayout But it’s just not there yet So look forward to that coming And then, well, we’ve built a layout, but really what you want is for us to build components for you Right? So Compose comes with a bunch of built in components that should make it really easy for you to get kickstarted First of all, we’ve partnered very heavily with the Material team Because we want to make sure Material is out of the box just there for you So we started creating the Material components They’re not all there yet But the team has already been hard at work to be able create those beautiful UIs And we already have things like buttons, checkboxes, and a bit more complex things App bars, drawers Some of these pieces are in their influx We’ll get there But you already have the basic pieces to build something like a sample app So say we want to build this Material card, building up on the example we had before with the image and the three texts Well, we’ll take the code we’ve had before I haven’t changed anything We wrap it in a card And we can give a card a shape, cause this is a material thing that you can choose what your corner should look like So, for example, I want rounded corners on my card We can style the text to look prettier than it was before with the three same styles And you’ll say, here you’re reaching into a theme text style This looks a bit weird So let’s take a step back to the Material spec So in the Material spec there’s a definition of all the typographies that you could define in your app So how you define all the styling of your entire app There’s a pre-set amount of textiles that you could use, just like they have a color system and a shape system We’ve built this out of the box for you So if you buy into the Material system we have a Material theme composable that allows you to configure all of the colors, all of the typography, all of the shapes you need for your app And then when you put this in your hierarchy, any other Material component you’re using will know how to read all these values by default so you don’t have to actually style them Similarly, you can reach into these values And that’s what I’m doing in this example So I’m saying, out of these three texts, I’m reaching into the style and saying I want H6, subtitle one, and body one It’s a very easy way to style if you’ve set up all your styling for your app correctly And finally, to finish the app, I can add a row with a couple of buttons Again, we’ve provided the material implementations of buttons So material defines three different kinds of buttons There is contained, outline, and text buttons And you will find that we keep the same terminology to make it easy to find things So we have contained buttons, outline buttons, and text buttons available So all of the Material components we provide we’ve built purely on the public API from layers below us So Compose UI core provides some foundation for us And we’ve built everything layered up on top of that So we’ve tried to not cheat with any private APIs This means that Materials should be a showcase of how you can build components We’re hoping they’re samples Right? They’re very useful components But at the same time, it should be code that you can go in, read, and see how we’ve done it, and take those examples for yourself We’ve also tried to break everything down into multiple layers, because you can break everything into more and more functions, to make sure there’s as many reusable bits in there as possible for everyone And as part of that, we’ve created this foundation level in the middle The main idea there is, there’s a lot of material that is not necessarily design specific There’ll be a bunch of gestures, accessibility that we’ve implemented to do a button So we can put the actual button in Material But then we can put the internals of the button in foundation So all the gestures, accessibility, other things that we’ve built that are not UI so that you don’t have to start from scratch You can already start from that layer and just build your UI on top And then no matter how many components we give you, there’s always going to be custom views that you’ll want to do There’s always going to be that designer that asks for a very strange thing that we had never anticipated So in the existing toolkit, you have to extend a view You have to take care of a bunch of things It’s a lot of work to create a custom view In Compose, it’s extremely simple You just have to create a function And there’s some building blocks that you can do to help you build up that custom view The two basic ones are draw and layout So draw will give you a handle into doing any kind of custom coding that you want Say, for example, we want to do a checkbox And a checkbox is just a square with rounded corners and then a checkmark Right? So let me walk you through the code to do this, cause it’s quite simple To draw the box, we open a draw tag We get access to a canvas and the sizes we’ve been measured to So we can easily calculate, how much do we

want our square to be? Apply the rounded corners, and then just draw the square Same for the checkmark We’ll open a draw We have access to the canvas and the sides We can calculate the three points that make a checkmark, and then just draw those on the screen So surprisingly simple The next part is layout Of course, we will try to provide as many layouts as we can out of the box There will be always something that you want to do that is extremely custom Well, you can reach down into the layout component I’ve tried to show here an example The most simple example I could find is a stack or a frame layout Right? Like stacking things one on top of the other So you will create a function that takes a bunch of children that it needs to place We open a layout tag We get access to these children that are measurable pieces, all the constraints we have And then we just have to go through two easy steps We measure each of the children to make sure we know what size they want to be And then we decide what size we want to be So, for example, in a stack I’ll probably want the maximum of the children to make sure they all fit And then I’ll place them each at the 0, 0 coordinate, cause that’s what a stack would do So then we’ll end up with an effect that is something like this Hand it over to Romain ROMAIN GUY: All right So what do we have today? Like I mentioned in the keynote, we just released our developer preview It’s called 0.1.0-dev02 So if it’s not clear enough, it is not quite ready for production But I want to show you some code and a demo So if you can switch to the demo machine, please All right So one of the simple apps we have is called JetNews You can see it on the right in the emulator So it gives you a good idea of the kind of things you can already build today We have horizontal scrolling lists, vertical scrolling lists The tech stack is already pretty advanced So you can do a lot of complex text layouting and styling So this is a very interesting app to look at It’s not a real app It’s not connected to a database or web service to keep the sample simple, but it’s a very good example of how to create your own widgets and to use the existing widgets So what I wanted to show you is what you see here So yesterday I built this little to-do list app So I’ve got the old [INAUDIBLE] icon in the bottom right And when you click on it, I just want to add list items And each list item will have a little bookmark icon that I want to be able to toggle So the way it works here, [INAUDIBLE] is a simple data class in Kotlin Is the text big enough, by the way, on the screen for everyone? All right I’ll assume it’s a yes So we have a data class It’s immutable Everything’s a vowel And you can see that night time can be a favorite, and just a description and an ID Then the actual model for the app is just this empty list of to-do items And it’s going to be an immutable list And I wrapped it into this object That’s probably not how you would do it in a real app, like using an object like this as a global object But I used this at @Model annotation And an at @Model basically turns this object into an observable object So whenever I change the item’s property, the UI will re-compose automatically And Adam will tell you more about this And if you want to know even more details, Dylan has a talk tomorrow where he explains how it works internally in the compiler This is the main part of the application So very similar to the way we saw this earlier in the keynote I have a vertical scroller I have a column I just iterate over all the items And then for each item, I create a row You can ignore the layout parameters But I have this bookmark icon So this is a composable I created And one of the things I really like about Compose– and that was one of the things we really wanted to do We wanted to make it easy to create your own widgets Very often in Android applications we end up with very large XML files, because it’s very cumbersome to create all those XML files, doing the [INAUDIBLE],, doing the includes, and the merge, and all that stuff And here all you have to do is when I first wrote this application, I wrote everything into these items composable And then when I saw that, I had this bookmark icon composable I just selected it I extracted a method using a refactor in IntelliJ And then I just added my add composable annotation And that’s all you need to do to create a new component You don’t have to extend from view of your group in override methods And then I just have a small spacer, and finally the piece of text that describes the item So the bookmark icon is here And here you can see another interesting– oops I’m revealing what I’m going to type That’s my cheat in case I forget what to do So my bookmark icon is pretty simple It takes one of those to-do items It’s read by a clickable So that’s how you create a click listener really And inside all I do is, I have this branch, and I say, if this item is a favorite, then I want to show the image that corresponds to the favorite state And if it’s not a favorite, I want to use the other image So it shows you that it’s not just about using four loops, one instance for each You can use any kind of control flow you want And it makes the code extremely easy to read And you could do this piece of code in different ways Anyway, so I have two callbacks in the app I have this toggle favorite, when we’re going to click the bookmark icon And I also have one when we click the [INAUDIBLE] So I’m going to try to write them So when we add an item, I’m going

to take the list of items, and I’m going to add a new item that I conveniently have in my clipboard So it will just give you a default string and an ID So if I rerun that– And you can note, that’s all I did Right? There’s no listener I don’t call re-layout, request layout, or invalidate it And when I click the button, a new item appears in the list And that’s all you have to do And that’s thanks to this @Model right here, because we observe that the items are changing But now I want to be able to toggle those little bookmarks Like when I click right now, nothing happens So the way I’m doing it is because it’s an immutable list– Let’s see if I remember So I’m going to do a map I feel so fancy when I do functional programming Let’s see Oops It.ID equals the item we clicked ID That will return a copy And I will do favorites equals not todo.favorites So I’m just toggling the Boolean Otherwise it’ll just leave the item unmodified All right That should work Relaunch the app So add a few items And now when I click, it toggles the icon Yay! Ooh Hm [GROANS] And that’s why always be prepared All right I will make it work Oh, yeah I used the wrong item All right Add items Bookmark Yes All right Now it works So again, the point here is to show you how easy it is to manipulate your data and to build that logic, and make it interact with the UI And more importantly, you can keep both kind of separated, or more separated than you could before But Adam will tell you a lot more about that Can you go back to the slides, please? ADAM POWELL: All right So this is the part of the talk where we talk a little bit more about kind of our design thinking behind Compose, and kind of what’s on our mind So in addition to the team’s ongoing work with Compose, we’ve also been spending a lot of time talking with the community Some of you, have probably been part of that conversation As well as running some more formal user studies And so here are some of the things that are really sort of top of mind for us that we’re excited about or that we think is really kind of important as you take it for a test drive So be careful that some of this isn’t implemented yet This is just kind of how we’re thinking about some of these open questions So please join us in participating in some of the design process So the first thing that really kind of hits you as soon as you start working with Compose is the data flow And while some of the tools available for managing that data flow came into Compose very early, or they existed before Compose did in the case of just some of the standard functional and reactive systems that you might be used to, the best practices and teaching materials around all of this is still kind of a work in progress Like we really are building something new here So the Android architecture components libraries have been really successful so far And it set the stage nicely, and established patterns that we’ve continued with in Compose itself So let’s go ahead and distill down some of those ideas and kind of see where they lead us Next There we go So we showed this diagram at Google I/O during our talk on compose there Dataflow is really the first thing that you encounter, like I said The shape of the API more or less enforces this top down, one way data flow approach It’s just functions calling functions And most people like this so far So it’s always good to have a single source of truth in your UI And it’s kind of frustrating when your views have a different idea about the state of your app than your application model does, which is definitely the case when you’re working with views in the average Android app So what do we mean when we talk about single source of truth in a UI? Well, it’s about avoiding conflicts or making sure that you’re not showing inconsistent data But it’s also kind of about who has write permissions to that state So with Compose you prevent inconsistencies by having the owner of a piece of state pass that state to the other composable functions that need it So the parameters that we call our composable functions with, they have to come from somewhere And the source of that data is kind of our source of truth, by definition And the interface that we use to pass those parameters really kind of determines what the composable functions can do with it, just like with any other function So you see access control layering like this in Kotlin frequently in the standard library You’ve got the list interface here, which only defines the read methods But the methods to actually change that state are defined in mutable list So even if I have a mutable list,

if I pass it to a function like the aptly named do stuff over here as the read only list interface, I can be reasonably sure that do stuff isn’t going to change my data out from under me So from a certain point of view, source of truth has to do with who has access to a mutable reference to that source of truth, and what kind of mutations a caller can perform with that reference If you can change the truth in any way that you want, are you yourself a source of it? Well, kind of So we use event handler lambdas kind of liberally throughout Compose, because it’s kind of a more restricted way to express a very specific mutation that you can make to state without actually giving away the keys in the process So here’s kind of what I mean by that We can show this just by using views with some of the APIs that you’re used to So here I’ve just added a click listener of the view And inside that listener, I’m using the fact that I have access to this myList variable from the example before And that’s our mutable list So that’s in my lexical scope So I can capture it as part of a listener block and just use it directly I haven’t actually leaked a mutable reference outside of this code snippet The block where this appears is the only place where mutable lists is accessible from anything I haven’t permitted mutation in any sort of uncontrolled ways by giving out a reference to it So all my view can do is just tell me that a click happened And I’ve defined how this higher level will respond to those clicks, given this layer’s access level So this is a really simple example And we’re just kind of using lists And we definitely did some in the demo as well It’s sort of a hand wave for, hey, this is the rest of the @Model I mean, clearly you’ll be doing something a little bit more sophisticated than direct mutations on lists So bear with us a little bit So a more real example might do something kind of like this So in this sort of sample view binding method, I’m setting a click listener and make some requests to my app based on the parameters that I was passed to when the bind happened So just like before with the mutable list, I didn’t teach buttons how to add and remove bookmarks I defined what a bound button should do when the button raises a click event And I used the context that was available to me when I bound it– that’s just the lexical scope– to form that definition So this is all pretty standard stuff So what’s actually new here? I mean, this isn’t unique to Compose here But it’s kind of the framing for what comes next, which is that Compose code is really, really dense We think that this is pretty great that you can remove so much boilerplate, but the trade off for that is that sometimes the distinctions of what you’re really doing become kind of subtle when it’s compressed into such a small space So let’s look at the same pattern that we just saw using Compose In this case, it’s not actually that much smaller It doesn’t look that much different We’re declaring the actual button as an implementation detail, along with its properties So what its text is and what’ll happen when it’s clicked Same thing But the syntax here is kind of interesting We said before that state flows down and events flow up But we’re passing both text and the onClick handler to button in the same way They’re both parameters So in a way, event handlers are just another kind of state that flows down It’s a state that the bookmark button created and that it owns So as far as button is concerned, it’s just this opaque token that can be invoked So when it is clicked, we make a request to this bookmark or object that’s not yet defined here to please add or remove the associated bookmark in response So the bookmarker might be backed by a local database API calls to some back end Really whatever I can fake it or test it outside the context of my UI But I’ve defined how the UI itself interacts with the bookmarker in one place here, along with the structure of the UI that’s being manipulated So bookmarker can be written to expose whatever operations that are appropriate to its clients like this one So the single source of truth here is preserved So that’s a single snapshot of that truth But the real power of a declarative UI framework like Compose is that it can keep up with changes over time So it’d be really nice if my code was always this straightforward, even when time is involved, and when changes over time is involved So we saw a little bit of that in the demo so far So if you want to update the UI in response to changes, well, you need your data to be observable And Compose is ready for that We saw in the demo that when you annotate a class with @Model that Compose will know when its properties change But why did we add something new here? The Android ecosystem has a lot of existing observable constructs So what gains do we get from this that justify adding something new? Well, we think that the answer lies somewhere between the ease of understanding of the kind of code that we can write this way, and also just kind of the ergonomics of actually using it in practice So let’s talk about live data for a moment Because it really has some neat properties for building UI Fundamentally, live data is a single value holder It’ll tell you when it’s updated So for our purposes in a UI, only the latest value matters Live data will conflate its values and only keeps the latest one There’s no such thing as missing an event You don’t actually have an event streamed There’s only the latest state And @Model behaves much in the same way in this regard So let’s take another look at an example,

kind of like the bookmarks code from before If you’ve worked with Android architecture components, view model, and live data, you’ve probably seen something like this before The view model sort of becomes this hub for a bunch of different observable data, along with some operations to request some changes to that data So we can reflect the same sort of structure with @Model, but you can see something kind of different here So the hasBookmark method that we used in the example before, it isn’t returning a mapped live data that has to be individually observed It’s just accessing the internal object’s state The list of bookmarks itself isn’t even public @Model has turned any normal reads of the object’s properties that happen within a special scope into observable subscriptions even if that read happens layers down the call stack If I called hasBookmark through some other helper function that I extracted in a refactoring or something like that, even in a completely different class, this would still work We don’t have to turn it into a stream or live data mappings each step of the way So if we take a look back at our bookmark button from before, we see that our UI can be expressed in terms of these snapshots of state and time And Compose can help manage the complexity of wiring these subscriptions together for us, even if the actual @Model objects might be several layers away across the call stack or across an object reference chain So Compose will automatically insert these observable scopes for us in composable functions We don’t even have to think about it So let’s go ahead and recap on that So we need observable data Compose will add @Model classes as a new tool that we have available But the cool thing about it is that it allows for the sort of cross cutting observability So we can write less plumbing and subscription management code in our apps But the thing is is that all these other observable and reactive systems are great You don’t have to leave them behind if they’re a natural fit for what you’re doing, especially if it makes sense in other layers of your application So if it makes more sense for the bookmarker at this particular layer that I’ve defined it to return a live data or flow, or something from hasBookmark, then we can still support automated but explicit subscription management by using an effect function, kind of like this One more There we go So that’s kind of the tour of the background behind some of that So really what’s left for us around data flow is kind of documenting recommendations for the question that’s kind of left that you’re probably all asking yourself, which is which of these tools should I use when So kind of establishing some of these guidelines and best practices are still kind of a work in progress here So more things that are a work in progress I hear a lot of questions about how to work with resources in Compose, and kind of what we plan to do there So let’s talk a little bit about that too Again, this is current thinking, subject to change But this is kind of where our heads are at at the moment So when it comes to using resources and the UI toolkit, we kind of think that we’ve learned a few things along the way And this is kind of a big one So really we need to avoid too many overloads Some of you might recognize where these are from We have a lot of ways to set an image ROMAIN GUY: It’s a convenience ADAM POWELL: It’s very convenient But the thing is is that this makes the view in question huge in terms of its own implementation But even worse, it means anything that tries to wrap or reuse one of these in a composable fashion has to reflect the whole capabilities of the API surface We don’t want this So it’s annoying for us to maintain And it’s even more annoying for anyone who wants to build something on top Now, there are a lot of reasons why you might want to offer overloads for your own composable functions And we would really be doing you a disservice by asking you to multiply that by the number of overloads that you might need to cover for this form of completeness because some underlying piece that you’re relying on offered all of these different ways of doing a single thing So that’s something that we’d kind of like to avoid So we’ve also seen a lot of other libraries appear to fill the gaps in between what Android views offer and what you need in your app So image loading libraries are a really great example of this There’s a bunch of great ones out there And they apply different loading and caching policies for images, tie into lifecycle, so on and so forth But really this is because a lot of resources are dynamic They might come from the web They might come from a disk cache or plenty of other places And tying into the appropriate lifecycle events as signals, it’s really not always fun There’s a lot to get right So by focusing so much on static resources in what we offered, we kind of created this privileged type of data It created a blind spot for us when we were looking at the system kind of from the inside And it should be much more straightforward to write these dynamic resource policy layers And static resources should have to play by the same rules So using the same public API services to operate So co-routines are awesome Romain mentioned sometimes I won’t shut up ROMAIN GUY: Yeah You never shut up about it You’re not the only one ADAM POWELL: There are more So we still have a few issues to work out with the experimental compiler around generating suspending code So we haven’t done a whole lot here yet

But our intention is to standardize on co-routines as our async primitive for working with resource loading, whether that’s static or dynamic So Android’s R class is also pretty convenient Having a bunch of symbols that’ll autocomplete for the resources in your app is pretty nice We’d like to keep that sort of convenience, but really all of them being ints is not so convenient ROMAIN GUY: And I ran into that yesterday while building the demo I would get a crash, because I had the PNG files and an XML file with the same name So the runtime would pick the XML file and try to load it as a bitmap And blah ADAM POWELL: Yeah You had some fun with that ROMAIN GUY: It took us five minutes to figure it out And we wrote the god damned thing [LAUGHTER] ADAM POWELL: All right I think that we might be able to squeeze one more into this list if someone will get out of the way there OK So layering is a pretty great idea too Because once we start talking about type safety and resources, and avoiding overloads, the natural question comes up, why should any of this be specific to Compose? We’re really kind of looking at how working with APK resources might be made better whether you’re using Compose or not And while we’re talking about things that are great, whether you’re using Compose or not, let’s go ahead and talk a little bit about view compatibility So we like Kotlin itself so much because you can adopt it in an existing project at your own pace incrementally, just a little bit at a time, one class at a time, one test at a time, et cetera So we’re designing Compose to be used in the same way So if you have an Android app today, you probably have a lot of views with layouts, maybe even fragments that you’ve extensively tested So they work Even once Compose graduates to a stable release, rewriting your existing and working code upfront probably doesn’t sound so great So you don’t have to So let’s take a look at a couple of the things that we have in mind here, and how this might look once we spend a little bit more time here So the first step in interop for us is being able to use just a little bit of Compose inside an existing app The API for this is about as simple as it gets It’s just one annotation And this may look familiar if you saw our talk from I/O earlier that you’ll be able to annotate a composable function It’ll ask the Compose compiler to generate a view subclass for you This’ll host an instance of that composable function, with appropriate setters, so on and so forth that you can use to feed it data in the same way that you would via its parameters So this will let you use Compose alongside your existing view-based UI So this still isn’t implemented yet, but we’re pretty confident that this is the way to go And that’s kind of the way that things always go Right? It’s the things that you’re most sure about are the things that you do last ROMAIN GUY: Well, someone has started working on this It’s just not finished ADAM POWELL: Right So the next step is a little bit less certain And this is something that we’re going to be doing some prototyping on And you can follow along with us in AOSP as we kind of play with some different ideas So even if you dive into Compose head first, you’ll probably still need to use views within that UI at some point Maybe you’re integrating a third party SDK that doesn’t offer Compose integration yet You still want to be able to use it So one idea that we’ve had is to leverage the new view binding feature that you might have seen in recent Android Studio builds So if you’re not familiar with it, if you have a layout XML file that looks something like this, view binding will generate some code that lets you consume it like this So you get a type safe object generated for you that you can use to bind values and listeners to it in code So you could imagine that turning into something maybe like this when you use it from compose While this might be nice for giving life to some layouts that you’ve already setup, it implies some additional work if you just want to use one custom view Another idea is that we could use the composition system itself to directly manage a view hierarchy The Compose compiler and composition runtime were originally designed to manipulate the view tree directly So here, rather than reusing layouts, you could use any existing view subclass as if it were native to Compose UI But a limitation that this has is that it might make things look a little bit too similar There’s really a lot of mismatches at the boundaries And some things, like, most notably, edit text, comes along with a lot of gotchas when you’re trying to use it in this sort of reactive style, where the single source of truth lives outside of that view So the existing view implementations still fundamentally want to own their state And layout contracts work differently, so on and so forth So we’re trying to figure out what the right balance is with some of these things So this, like some of the other design spaces that we just talked about, are going to be occupying a good bit of our time over the coming weeks So we want to be sure that interop with your existing code is as straightforward as we can make it, while not leading you down a path that ends up creating additional work if your constraints change So we’ll keep you updated as development continues, but hopefully by now you’re asking another question CLARA BAYARRI: So you’ve heard what we can do You’ve heard what we’re trying to get to do But how do you play with it? Well, today we’ve published a brand new website So d.android.com/jetpackcompose We’ve updated the content in the Jetpack Compose website, including, for example, how to file bugs So please, go check that out As part of that content we’ve published a tutorial And the tutorial will guide you through the basic principles of Compose, kind of similar to what we’ve done today, but much more in detail So please go check that out You can read through it and it will make sense Or you could go and download the new Android Studio build that supports Jetpack Compose It should be up soon I think [COUGHS] ROMAIN GUY: Sorry [LAUGHTER] CLARA BAYARRI: You will also get a new template– ADAM POWELL: He’s uploading it now CLARA BAYARRI: –for a Compose activity that will set up all your dependencies and everything So you don’t need to go read random blog posts that

will tell you how to set it up You can try the new preview that we showcased at the keynote You’ll be able to preview what you’re building with Compose You’ll be able to see the sample So we published JetNews as our sample It showcased everything that is there now and how you can use it to build this news article app And then other things that you can try while you’re here at the Dev Summit, there’s two codelab sessions happening The codelab is also available online if you’re streaming And we have two talks that you should go check out What’s New in Android Studio, where Tor and Ja will walk through the tools that we’re building for Compose as part of that And tomorrow we have a talk from Leland, who’s in our compiler and runtime team And will explain a lot more on how the insides of Compose work, and kind of demystify the compiler, and what we’re doing behind the scenes Thank you very much ROMAIN GUY: Thanks ADAM POWELL: Thanks [APPLAUSE] [MUSIC PLAYING]

You Want To Have Your Favorite Car?

We have a big list of modern & classic cars in both used and new categories.