Android Dev Summit 2018 Livestream | Day 2, theater 1

Hey, good morning, everyone We invite you to take your

seats. As a courtesy to the presenters, we ask everyone to

mute their devices at this time Good morning. And, welcome

back Everyone, good morning. Will you please welcome back to the

stage, dan DPAN dan Thank you for getting here bright and early in the morning We said things were starting a half an hour early. Welcome to everyone on the livestream and all the people who were watching on our viewing parties. One is we do not have lightning talks today. Please, you know, try to stay for both 20-minute sessions, if you can. Check the

schedule, one more time, to make sure you don’t miss your favorite As you noticed, there was a schedule change. The D8 and R8 talk is not happening Mr. Wharton has a special project and we congratulate him on that. Instead, we’ll have Trash Talk But, the exciting part, right now, is we have an esteemed group talking about foldable [Applause] Good morning, everyone. My name is Adrian Roos. I’m a software engineer I’m Andrii and I work on multi-display I’m Jisun, I’m engineering director By now, I’m sure you’ve seen the announcement that we’re partnering with Samsung and we’re diving deeper into what that means, what we’re doing to support developers for foldable devices. Jisun is here to talk more about what Samsung is doing. So, with that, I’m going to hand it over to Jisun Thank you. So, again, I’m Jisun from Samsung Mobile and I’m going to talk about the new form factor device, which you announced at the Samsung Developer Conference. Okay So, I will cover more information about the device, itself, and also, we’ll talk about the experience, the new foldable device will bring to the users We all know that the smartphone has been providing new experiences for the last 10 years. And it actually changes the way people think, act and also communicate. Additionally, it also opened up a lot of new opportunities for the developers. Now, we believe a foldable phone is one of the next game-changers, which will provide a very unique experience to the users and also new opportunities for the developers to drive innovations Okay. So, now let’s talk about the first Samsung foldable phone. The first Samsung foldable phone is designed to be multi-display with two screens and also supports multi-activity window So, let’s take a first look at what the actual configuration on the display actually looks like So, this is the main display, when the device is unfolded The main display is large enough to provide a very unique experience. The experience becomes richer and more immersive. The experience was hardly achievable, even from the larger screen smartphones In addition to the experience from a single larger screen, two multi-tasking will become available to utilize this larger screen with up to three multi-active windows When the phone is actually folded, we still have very useful and portable cover display to use. In this mode, the experience is very similar to your daily smartphone use, but compared to the main display, the experience is more to be focused and handy and quick interaction, to actually leverage the small screen So, having said that, here are some numbers that you may be interested in. This is the specs and the dimensions of the actual screens. So, 4.5-inch cover display provides 21:9HD plus resolution and a

320DP 7.3-inch main display 4.2 plus resolution with the same 420DP with 585DP is the smallest width. These are the numbers you may need to know Now I will show you some expected user experience with some examples. So, comparing the experience between the existing smartphone and fold main display, the foldable is foldable and can locate larger to the application and it actually enables the contents, on the screen, to be richer and more detailed, as you can see from the screen On the cover screen, when device is folded, I said the experience can be optimized to provide quick and easy access and interaction. While the device is fully-functional, like a normal smartphone Access to the quick panel or notification or call or messaging is good to highlight the cover display. We know that you may not want to unfold your phone to take an incoming call While the cover display and main display, each one provides its own very unique experience. It is between them, not separate nor disconnected. Rather, the user experience, between the display, is very continuous and connected seamlessly As an example, if you want to search for the location of the center from a map, you can do that with your phone folded However, if you unfold your phone, the application still continues to run. Even more, unfolding the phone actually provide more information with more visual cues, like what’s nearby and what’s the location to the other point of interest Using the gallery app is similar. The app experience continues between the folded mode and also the unfolded mode Multi-active windows for multi-tasking is also one of the key features. So, while watching a YouTube video, if you want to browse a website, you can just open up a browser and browse the website while your video keeps playing Moreover, if your friend sends messages and the notification pops up, it can grab the notification and drag it to a third window, like this, to continue chatting and browsing, while your video still keeps playing So, we have this expected experience with the new foldable device, so now Adrian, from Google, will talk about developer guide and also some Android support to make your applications better-fit for the foldables Thanks for sharing that, Jisun [Applause] So, let’s talk a bit more about how you can take advantage of foldables in your apps and kind of the guidelines we could recommend to do so. So, first up is screen continuity. It’s what we call the concept of continuing what you’re currently doing after you fold or unfold the device. And, an example here, we have — you have a map You’re looking at on a folded device. And, you would like to see maybe a bit more about the surroundings of the place you’re looking at. So, as a user, you unfold the phone and with the continuous experience, we’re still looking at the same place, your state is maintained and the phone can take a bit more advantage of the form factor And this is actually not really a new thing in Android, right? We’ve had to deal with similar

situations before, with things like screen rotation or changing — changing screen sizes or — sorry. Changing window sizes in multi-window So, why should you care about continuity when you build your app? Well users unfold their devices for a reason and usually that’s because they want to dive deeper into the task they’re currently doing. So, that really works best when they are not interrupted in their experience when doing so and can continue where they left off before unfolding So, for a satisfying user experience, it’s really important that this works well That seems great. Now, how do you actually pull this off? Well, as I said, Android is familiar with this and we’ve built a system to deal with that. Folding and unfolding the device will be treated as a configuration change in the screen size and screen layout categories. And, to support you with that, the Android system, by default, re-creates your activities when a configuration change happens This has the advantage of taking care of any layout changes you might want to make when taking advantage of the new configuration. But it also means that you, as the app, are responsible for restoring the state the user was in after that activity’s re-created To support with that, we have a state facility and introducing a new Jetpack library called ViewModel to support you with that Alternatively, you could also decide to handle the configuration change yourself by just applying it and adjusting your layout. To do that, you can declare that you can handle the configuration change in your manifest, but that means you’ll have to manually adjust the screen size Make sure to correctly implement multi-window and declare your activity as resizable Now, next up, we’re making some changes to the lifecycle in multi-window. You can see the current behavior on the left That is that only the activity that the user last touched is in the resumed state while all the other are in the paused state That’s a bit confusing to users because it’s not immediately able to see why some are in a less interactive state and it’s one more thing you have to keep in mind, as a developer, when you target multi-window. We’re introducing multi-resume mode It’s pretty simple, really. All the activities in multi-window that are at the top and are visible are all in the resume state Now, Android Pie didn’t ship with this behavior originally and so we’re making this an opt-in behavior in Android Pie It will only be applied with the app developer ops in and the device manufacturer actually implements this feature according to our spec But note that in future versions of Android, we’re expecting to make this mandatory behavior So, let’s say you have an app and want to take advantage of this simplified lifecycle, how do you opt in? Again, you add one flag to your Android manifest. There’s one caveat, though, because there are multiple activities that can be resumed at the same time. Be really cautious around code that stores the one resumed activity because there might now be more than one of those. Be cautious around libraries and frameworks that might make the same assumptions And with, that I’m going to hand it over to Andrii, who is going to talk about multi-window/multi-display So, let’s talk a bit more about multi-screen devices. A an activity can be launched on a display. Let’s see what it actually means for your activity. First of all, when an

activity is on a non-default display, the activity context is different from non-visual application context, also available from broadcast receivers and content providers The context of a visible entity will be adjusted for the display area where it is shown. If you use the same API to get the current display and use a different context type to ask for it, you will get different results. The current display, you can get, is from the activity and the application context will always give you the default display Different context also mean different resources and configurations. It will be automatically updated for you All you need to do is request them from the correct context When you want to adjust your UX, you should be using an activity Keep in mind that the user may move your activity from one screen to another at any point In most cases, you can expect this place to have different sizes, densities and resolutions. This means the activity that was muted will get the configuration change. If it is declared to handle the change, it will be notified with the new config. If not, it’ll be launched To deliver the best experience, we encourage you to handle configuration changes whenever it’s possible and if your app needs to know what display, you can find it on ondisplay What if you want to take advantage of these additional screens? How do you use them? The first step is to get information about the displays You can check their flags, metrics and states. For example, you can look for live screen to provide media content or filter out the displays that are currently off Once you have determined what display you want to use, you can launch your activity there using the activity options API, available in Android I/O. If you want a new instance of an activity, you may want to use corresponding flags and use new task for this launch Sometimes the system may restrict activity launches to some certain displays, for example, private displays. You can expect this Remember that there are several platforms that actually have multi-display devices. Phones is one example we have covered today Next, there is desktop mode When you connect your phone to a larger screen for improved productivity or entertainment Android apps running on Chrome OS. In both of these cases, the apps are usually running in free-form mode and the user expects them to be freely and smoothly resizable Last but not least is automotive Android. There may be many screens in a car. For example, kids in the back seats may be playing same or different games while the driver is using navigation For apps, in general, there shouldn’t be too many differents. To verify your app behavior, on any Android device running O or above, you can create a simulated display and launch your activity there At this moment, simulated display does not handle touch We are working on improving this and we are going to be adding new developer tools With all this new and existing platforms, you can choose to optimize your app and build a multi-screen experience. You can test your app and set corresponding launch modes Don’t forget that in this case, multiple activities may be focused. Also consider using the shared data and take advantage of other Architecture Components [Applause] So, we’ve talked about what’s available today. Let’s look more at what’s going to be in

the future with foldables and multi-display devices. In the short-term, for Android Pie, we’re working on developer guidelines and we’re going to show you how to best-target foldables and multi-display devices. We’re also working on a blog post that’s going to go live, which will have more information about everything we talked about. And we’re also working with Samsung to release an emulator where we can develop and test your apps against the configuration change behaviors and the multi-resume behaviors that their device is going to have Looking a bit more into the future, with future versions of Android, we’re implementing support for foldables and multi-display devices and as part of this, we’re also going to improve the emulator, so it will have support for simulating all those foldable and multi-display behaviors, as Andrii also mentioned Finally, some pointers on where you can find more information In the following days, we’ll have this blog post up. There’s a Samsung developer site where you will find more information about Samsung’s devices and their guidelines and for testing your apps, the Samsung emulator will also be available on their website some time in Q4 Okay. At this point, I would also like to thank you for all the amazing experiences you developers are building for Android and we’re really excited to see what you will do next and what you will do next on this next form factor of foldable devices. Thank you [Applause] be in the Q&A area where you can talk to us later, in the next break All right. I just wanted to have a few minor things. One is that you noticed that we’re going to have these Q&A slides These have these QR codes and those allow you to rate all of the sessions here at the Android Dev Summit. Please let us know We did a lot of experimentation with content this time Second thing is, I know we didn’t have the D8 and R8 talk, but we have the engineering lead out in the sandbox area. If you’re interested in R8, please go out and ask questions in the sandbox area. You can rate all the sessions, all day long, today, from the single QR code So, thank you very much. Enjoy the rest of your day Everyone, the next session, in this room, will commence at 10:20 a.m. Thank you Everyone, welcome back. We invite you to take your seats

Our program is going to be under way in three minutes. As a

courtesy to our presenters, please mute your devices

Welcome, everyone. Please be

seated

[Applause] Good morning. I’m Chris

And I’m Alan We’re here to talk about pixels. We need to think about the actual technologies. There are two prevailing technologies, LCD. The majority of devices are screens, from the mid-level to the high-level. And even in platforms, they’re moving to that, as well LCD stands for liquid crystal display. They work with what they call liquid crystals so each pixel is made up of a color channel. They require a backlite. So, those liquid crystals don’t illuminate themselves. Now, most of the power for an LCD display goes into that backlite. So, more brightness is more power Olet displays are diodes, which actually emit light themselves so there’s no need for a backlight. The good thing, here, is that they allow a true black. So, with LCD, the way you achieve black is by turning all the crystals on so you can never really get that dark black Olets are different. They don’t turn the pixel on and that’s how you get black. That’s where the power is And the power is powered by emitting light Now, there’s a number of arrangements, you have R, G and B. So, let’s more straightforward and mentally simple. There’s more complex ones, like RGBR Each pixel only has two channels. It’s a way of expanding pixel size without fitting as many LEDs in it In terms of power, more LEDs equal more power usage. We’ve done stats over the last year or two and the display tends to be the biggest power user of your device. You see a chart, the display, the more power it uses Everyone assumes this is the case. But the thing is, it’s actually quite linear. Again, kind of simple But then we start comparing oled devices versus LCD screens and it’s the pixel versus that. We have a screenshot of maps in a normal day mode and a night mode. The reason we use a screenshot is because we didn’t want the differences been iOS or Android to show it The actually amperage on night and day is the same. That doesn’t change because it’s an LCD screen. But on the pixel itself, because it’s an oled display, the power drops down by 63%. The biggest power user on your device, by using a dark theme Going more into it, when you have individual pixel colors — so, we did a test where we displayed one color on the display. And, the actual color, itself, makes a difference in power. Blue is 24% more power than, say, green or red. And then, another chart, which is pretty much a summary of the previous chart, but you can see the black is using the least amount of power. It goes up and up until we get white. Because

white uses channels for every one, it’s full red, full green, full blue, it requires the most amount of color and guess which color we’ve been pushing you towards? We changed from hollow to this white theme and we shot ourselves in the foot in terms of power Let’s look at Google apps over the last year and the power savings they’ve been able to have. Here ‘s YouTube, full brightness You save 43% of your battery usage. When you’re playing a video, it doesn’t matter anyways Now when it’s paused, we save even more, it’s 60%. My guess, here, is because the overlay of the video actually darkens the video, you know, we use an even more dark color so we save more power. This test, itself, depends very much on the video content. If you have a video that is fully white, you’re not going to save so much Gboard is a good example. Users can control this and save 20% of your battery or the display use of the battery, just by switching to a dark theme Finally, on Maps, this is the example of dark theme and where it is really great because it has the obvious benefits of the battery. You don’t want Maps being a really white theme when you’re driving at night. So dark theme, here, makes the app more usable in a nighttime setting And now Alan’s going to talk All right. So, how can we embrace the dark side some implement dark mode in our apps? Going into dark theme. Which will not save us any battery here, but it will on your devices. So, you may remember Night Mode from the developer preview of Android last year or the year before that or the year before that or the year before that. But, we released Day/Night support in app compats. There’s a great blog article about it. Our recommended way to implement Dark Mode in your app and basically get it for free is Day/Night. You can get this almost for free. The stock widgets will respond to the changes in the device’s Night Mode and you can toggle between Light and Dark mode. This is the demo from the AndroidX checkout. If you have it from AOSP, you can take a look It’s one line of code to switch between whatever theme you’re using before and app compat You simply take whatever your app theme is and have it inherent from one of the day/night themes. Everything might just work You can also apply a overlay theme dynamically at runtime So if you want to have a pure black oled themes, there are some apps that already do this or a pink Hello Kitty theme, you can do it at runtime. If you want to learn more about overlay themes, Chris and I talked about those at I/O a few years ago This ensures any time a theme is set, you will then immediately overlay it with the black theme or a Hello Kitty theme and any views that get inflated will be using that theme correctly All right. Either, way, you’re going to want to structure your app on theme attributes. All of the platform drawables heavily-rely on theme attributes to obtain their colors. Color foreground, color control normal, color accent. The thumb — sorry, the switch that you can drag left and right, the thing that sits under that is colored light gray when it’s enabled. And dark gray when it’s disabled. The implementation of that is just a color selector, a color state list that refers to the color attribute, which is white under a light theme. Black on a dark theme and an alpha. We vary that based on light and dark themes There are no colors hard-coded

here. We’ll talk about this more, later today, in a talk with Nick Butcher about themes and styles All right. So, I mentioned night mode showed up. The qualifier has been there since SDK 8. It was opened up for general use in Android N, so the ability to set the night qualifier system-wide, there are some apps that accidentally set it. Messenger has been doing that recently, it has been fixed It’s a research qualifier similar to portrait or landscape. You just create a drawable/night and if you have resources that are difficult to extract theme colors out of, say you have a welcome splash image that is complicated, you can get a dark version of that and it’s too complicated to put in a vector drawable, you can drop it in drawable night. You’ll pick up that drawable automatically Same thing for colors, if there are colors you want to switch, say your accent color is darker, you can extract that to a named color resource, have one version in colors, one version in values night So, here’s what the theme implementation can look like If you want to switch your parent theme based on night qualifier, you define it once in values and once in values night and give it a different parent When it is non-night mode, you’ll pick up the light theme when it’s referenced under night mode, when the night qualifier is on, you’ll pick up the night theme We have the same color referenced two different ways It will pick up black under non-night mode. It would pick up white under night mode When you can do update your app, maybe do a little bit of restructuring. Take a screenshot of your app, invert it, see how it looks. Get a sense of whether there are images you’ll need to have an alturnive version of. We have avatars, maybe we want to change the background colors a little bit, so that may mean extracting theme attributes or different sets of PNGs to drop into drawables night Next, you want to take a survey of the usage of colors in your layout XML and in your styles Set the parent of your theme to be something dark, theme.appcompat or theme.material. You’ll want to look and see if you’re losing contrast. What you you see should look like it All the background colors and foreground colors were hard-coded to be light theme The one thing that wasn’t hard-coded — and you can almost see it here — is the label for first name, which is now invisible because it’s the only thing that’s correctly pulling in the dark theme color attributes. So, this is going to require a lot of work The hard part is doing that work. So, you’ll want to refactor your colors as much as possible. Take any hard-coded layouts in your XMLs and move them to named color resources You can base those on values/values night. If you want to do more than one theme, you’ll want to extract those to color attributes that have some sort of meaning in your application. We have text color primary, we have color ax sent, we have color primary. You should be using those as much as possible and certainly take advantage of theme attributes for specifying colors, propagating those into your lists and layouts You can convert your PNGs to alpha masks and convert tinting You can wrap those where a bit map. We’ll talk, again, a little bit more about this at the themes and styles talk today Next, you move over and

get automatic switching in night mode. Here, we have the Twitter app, which has a very obvious affordance for switching between day and night. So, if you tap this, it goes into dark mode There is a platform specified dark node so you may have a tristate You you’ll also want to test that your application works when Night Mode changes. You can use ABD, open your app, once you’ve implemented the day/night theme, toggle it into night yes. It is going to go through a full on-display and re-creation and preserve using data On pixel 3 devices running P, night mode will switch and it enters battery-saving mode. You can toggle it from developer options and push might node to be always on, always off or one of the legacy things we have is switching based upon time of day You can learn more in the themes and styles talk that I’ll be giving with Nick Butcher later today. If you want to learn more about the lower-level things, Chris and I gave a great talk at Google I/O. So that covers anything you want to know, but have been afraid to ask about themes and styles We will be outside in the Android Lounge to answer any of your questions Thanks, everybody, for coming Please embrace the dark side [Applause] Hello, welcome to Improving Battery Life with Restrictions My name is Jingyu Shi, I’m a partner developer Hi, I’m Amith Yamasani Today, we want to start with this notification we’ve all received, hopefully never around this time of day. Knowing that our battery’s running out can be really frustraing and sometimes scary depending on where we are and what we’re doing at this time. These days, we rely so much on our devices for navigation, talking to our friends and family, taking pictures and even translate for us when we are traveling in a foreign country But all these cool features and amazing apps that you built cannot help the user if their battery is dead. So that’s why today, we’re talking about how we’re going to improve battery, with your help, hopefully. And this is what we’re going to cover. First, we’ll talk about what’s consuming power and how we measure power consumption and then we’re going to go through the power-saving features we’ve introduced in feature years and how your app will be affected by these restrictions Next, I’ll pass it over to Amith to talk about what’s consuming power Hi. Quickly walk through how we actually estimate how an app consumes power, how much power it’s consuming on the device These are the typical components, hardware components that are consuming power. I’ve highlighted the top consumers You got an earfull of display Running at high frequencies is also pretty expensive and transferring data over the cell network is quite expensive, as

well So, when each device is manufactured, the OEM has a power profile. What it contains is the average current drawn by various subsystems we want to measure in realtime and, for example, if you turn the screen on, at minimum brightness, it might be about 100. If you crank it up to full brightness, let’s say it add another 300 So, we keep track of that in realtime. CPU has different power consumptions At runtime, what we do is, there’s a subsystem called battery stats. It tracks what each app is doing. It measures how long it’s consuming each of these resources, like, how much CPU time, at what frequency, how many data packets it’s transferring and so on and we multiply with the power cost for each of those and we get an approximate estimate of how many hours the particular app has drained and we rank the apps, presented to the user, so they can see that in settings and learn for themselves what is really draining their battery So, let’s talk about how the OS is trying to help the user extend their battery life. But, first, broadly-speaking, there are two reasons why the app runs, the user’s launching it, it’s running in the foreground, user’s actively using the app As developers, that’s something you don’t want them to not do, but that’s a whole different topic about digital well-being and trying to, you know, help users control how much time they spend on apps But one note I want to leave here is there’s a concept about suspending apps and that’s something you might want to read about and how that impacts your app if the user suspends the app for, let’s say, the rest of the day But we’ll focus on how we try to limit background activity from an app. An app can schedule background work by using jobs or alarms. It can also register for call-backs for external triggers like push messages or walking past a geofence Over the years, we’ve introduced several features, in the OS, to save battery. First, in Marshmallow, we introduced Doze It puts the device on a deep sleep. Let’s say you left it on your desk or nightstand, it basically shuts down a lot of the background activity so that you can really extend your battery life But this is not really how we use our daily phones, right We’re walking around with it So we came up with Doze on The Go. It puts it to sleep lightly. It’s not in front of you, you’re not using the screen so it can shut down some of the background work You’re probably all familiar with the Oreo restrictions on background services. As of this month, everyone needs to target Android Oreo above But we’ll focus more on what’s new in P, Adaptive Battery, Battery Saver. Adaptive Battery is a revolution of App Standby that was introduced. It put app in two possible states, active or non-active. Adaptive Battery extends this into four buckets Based on usage, we move it to some other buckets. For instance, if you are Google I/O and you install the I/O app, it should go to the rare app because you haven’t been using it So, how does the OS assign these buckets to each app? It starts off when you’re installing the app in another bucket, it’s not shown here, it’s really not that relevant. Once you launch the app — or every time you launch the app or any kind of strong interaction, like clicking on a notification, the app goes the

app bucket and it stays there for awhile, maybe in a few hours it comes down and starts applying restrictions. And a little later, most frequent and then to rare and then we uninstall your app. I’m just kidding. We don’t do that [Laughter] If you’re looking at a notification, it’s not a clear indication that it’s an active usage of the app, so we put it in a slightly-restricted state, which is the working set. What is actually adaptive about this is if the device has a machine learning algorithm, it watches your usage patterns, learns over time and decides, okay, this app is probably going to be used in the next couple of hours, let me put it in the active set and maybe it can freshen up its data. And once it feels that maybe the app is not going to be used for awhile, it might move it down in to one of the lower buckets so this really approves your ability of the amount of apps it uses in the background It’s not your fault, you don’t know when the user’s going to launch you so we’re trying to help with that Restrictions is another feature We limit what the app can do in the background. It’s mostly met for apps you want to do in theforegrounds. There are two ways the app can go into this state. The user might see, in settings, that your app is draining battery and decides to manually restrict the app. The system is monitoring certain criteria and if it feels it is doing anything excessive, it suggests to the user, do you want to restrict this app because it is draining your battery in the background These are things we will improve and OEMs are able to add this The usual jobs, alarms, full-ground service. As far as the user’s concerned, it is a background thing if you see something happening with a notification and it’s doing work in the background. FCM, as of January, will be restricted as well. So you won’t get any messages when your app is in the rest state. You don’t get location updates and one thing that’s unique about app restrictions is even while the device the chargeing, we don’t let you run in the background The reason is, this is not just about saving battery, it’s also aboutabout annoyances and maybe privacy concerns It’s very similar to how restrictions work. Some of the differences are foreground is fine to run on Battery Saver There are no restrictions on push notifications And, one thing that’s new, in Pie, is we turn off location services completely, at least on pixel devices, OEMs might not choose to do that You can ask user stats, what is your current standby bucket, at this moment. If you want to debug something, you can also get historical information about your standby bucket changes. You can check if you’re background-restricted right now and maybe you want to tell the user something about that Please don’t nag the user. If they don’t want you to run, they don’t want you to run And, you can also check if Battery Saver’s on, internally, it’s called power saver mode Thank you, Amith So, how is your app affected? So, any time to the system, your app will be one of these two states. It will be either in the foreground or the background. And whenever your app is considered to be in foreground, all these restrictions are lifted so you can run whenever you need to When your app is in background and the device is not charging all of the Battery Saver features that Amith just talked about, any of them could be enabled, which means your jobs, alarms, network access and FCM messages could be restricted

Next, we have some really beautiful diagrams, which will show you how they are affected First let’s do scheduled jobs Given all the constraints you have on the job is satisfied ified, these are the things that will affect how it runs. If it goes, your job will defer to the maintenance window. If the user decides to turn on Battery Saver or app restrictions, meaning restrict your app from that battery setting, your job will be deferred until the user opens the app or the app is in the foreground Your job could be deferred up to 24 hours, that’s when your app belongs to the rare bucket and that’s the worst case, which means that even in the worst-case, your job will still get run every day So, similarly, for alarm manager alarms, it will affect when your alarms fire. When it’s in Doze, your alarm will be deferred to maintenance window. If the user turns on Battery Saver or restrict your app, your alarm will be deferred until your app is in foreground. And finally, to the app standby bucket, your alarm could be delayed up to two hours if your app belongs to that rare bucket If your use case requires that exact time execution, then, for example, if you want to remind a user they need to take medication or a TV program that they subscribe to is about to start, so for these use cases, you can use this idol method so your alarm will fire on time But you are using alarm manager to wake up the device frequently and imagine that every app is doing that at a different time, you’re draining a lot of battery. That’s why we have the excessive wake-up on your vitals page. If you see it on vitals pages, it’s caused by alarm manager, I would recommend you think about maybe you migrate to other APIs If you are sending push notifications, you are probably already using Firebase Cloud Messaging. When the device is in Doze, your priority messages will be deferred to the maintenance window This is because high-priority FC FCM message, they’re triggered to send a notification to the user. If they turn on Battery Saver, still your messages will be delivered, as it is As Amith mentioned earlier, if the user restricted your [no audio] audio] They will apply on any app that’s running on Android device, no matter which target SDK you’re targeting. So, our first advice to you is please test your app. We have ABD command. You can use to put all your apps in this features to see if your push notifications are coming through Except for the high-priority FCM

restrictions, none of them are knew. If your app works well under Doze, it’s very likely that you don’t need to change much to work with these features Our second advice to you is whenever you’re running task in the background, please keep in mind to use this Lazy first design principle. Try to reduce the work KROUR — you’re doing in the background. Can this wait until my app is in the background? If you really need to run in the background, try to defer that work to a later time, say, when device is plugged in or think about that exact alarm Does it have to happen at that exact time? Can it wait? Finally, try to do the work in the background. In Lollipop, we introduced Job Scheduler, which is a way for you to help the system to intelligently batch all the background work and this year, we introduced WorkManager in Jetpack, which makes running background work better. When it is stable, it will be the recommended way to do background work. So, with that in mind, let’s look at this upgraded view of how you do things in the background If you need to execute a work that is deferable locally, WorkManager is your answer. If this work is triggered online, then you would use an FCM message with WorkManager Meaning you would want to use FCM message to notify your app there is work you need to do and the in message handler, you queue that work. If your user case doesn’t fit with either of these cases and you need to run something at that exact time, then you would want to use alarm manager If this is something that the user started, user is aware it is happening and it must happen immediately, you would use foreground service. But please, whenever you are using this foreground service, add that notification because there’s nothing more frustrating about seeing a bunch of notifications and there’s nothing I can do about it. Please add that action in a notification for user to stop this service and notification is dismissed If you reach the end, I would say go back to the top or you should wait until your app is inforegrounds So, we have a talk later today, at 1:00 p.m., please go to that to learn how to use WorkManager to do background work. We also have a lot of best practices and guidance, how you can help us to help users save battery. Please visit to learn more And, we will be in the office hours this afternoon for any questions. Thank you Thank you [Applause] Everyone, the next session in this room will begin in 10 minutes. Thank you Welcome Android Dev Summit

We’ll be back at 1:00 p.m

Cool. Thanks for coming Welcome to Working with

WorkManager. My name is Sumir Kataria

I’m Rahul Ravikumar We both work on Android

Architecture Components, particularly, WorkManager. Let

me grab my — [Laughter]

All right. We’re going to give you a state of the union about

WorkManager. I want to give you an abbreviated guide to

WorkManager. So for those of you who haven’t used WorkManager

before, we want to give you the basic APIs. We’re going to talk

about WorkManager, the things you’ve asked and also the new

changes we’ve made since I/O So, let’s talk about the state

of the union. There have been 11 releases of WorkManager since

Google I/O and these are alpha releases. Today was the one —

was the 11th one. And, beta’s coming soon so those of you who

watched the keynote yesterday may have heard beta’s coming

this month. This was news to us, too

[Laughter] So, we want to give you an

abbreviated guide to WorkManager and what is it, for those of you

who are completely new to this? It is

a library. It wraps alarm manager and those of you who

have used Job Scheduler will find the concepts very familiar

So, let’s talk about work You’ve got a unit of background

work — and we’ll talk about how we create it. You’ve got it and

how does WorkManager execute this work? This is a graph that

might help you. While your process is up and running, we’ll feed to this executor that we have. You can customize this thing. But your process may be killed and WorkManager is guaranteed to do work. It may defer it, but it will do it when the constraints are met. If you’re API 23+, we used Job Scheduler and before that we used alarm manager. Whenever the signals are met, let’s say you put in a two-hour time delay when you have network. When all those conditions are met, it will still go to the same executor All right. Let’s do a quick API walkthrough. So, the fundamental unit of work, in WorkManager, is a Worker. Here, I’m defining a calculation Worker. It extends the Worker type. The only thing you need to do is extend do work. Here, I’m returning a success. You can also return a retry or a fail. I’m doing some expensive calculation on the background thread so you don’t have to worry about threading here because WorkManager is guaranteed to schedule your work Here, I’m returning a result of success synchronously. How do you make that work run? So, for that, you need to inqueue a work request. One is a one-time and one is a periodic work request I’m using a one-time and building it with the calculation. I’m telling it initial delay. This tells WorkManager to only run the work after two hours has passed since the point of inqueue. I’m setting the charging constraint It is only eligible to run when the device is connected to or charger — when the device is actually charging I’ll talk about tags in more detail and I’m calling .build Now I need to do is call get- instance and get the work. And it — if you want to keep track of what state your work is in, you want to call get work info by LiveData. This returns a LiveData of a work info. That is the state of your work and LiveData here is a lifecycle of observable. So once you attach it to a LiveData owner, once

you inqueue the work, once the constraints are met, it’ll go into running and then finally, it will go into succeeded state Remember the tag we added when we built the one-time work request, you can get it with data. You associate it with a work request and there can be one or many. You can assign the same tag to multiple things. It is by tag, LiveData. LiveData again. A list of work info And again, I can do the same things I did in the previous slide So, one of the coolest features of WorkManager is the ability to chain work. So, that helps you define a graph of work and here, I’m asking WorkManager to begin with A, B and C and they’re work requests. D and E are only eligible to run once A, B and C are done. I’m asking WorkManager to run A, B and C to run in parallel. And, finally, I’m calling on this again. FGNH will only run once all the proceeding runs are done. Don’t forget to call inqueue Returns are work continuation The work continuation is a node in your graph. This lends to a very fluent API. Every time you call it, it calls a new instance of another continuation Finally, don’t forget to call inqueue. When you chain work, the outputs of the parent work request become inputs to your descending work request or your children. This helps you manage and send state from parent work to the descendant work Now, finally, there’s WorkManager that also exposes the API to cancel. If you want to do that, you can cancel work by ID and every work request has a unique ID. Here, we are canceling work by that ID and you can also cancel work by tag So, those are the two APIs And, that’s it And I want to point out that all the things — all the APIs we’ve been showing are for alpha 11. You may notice some slight changes for those of you who have been using this API before But everything is live today So, let’s talk about how to get the most out of WorkManager. It includes, how do I do a certain type of task? And the biggest one that we get a question about is threading. How does threading work in WorkManager? So, we talked about a work request, Rahul just mentioned that. You inqueue it. We have an internal task executor. It is a single-threaded executor The inqueue goes to that. Every app that the uses WorkManager has a WorkManager database This is the source of truth This is where we keep track of your inputs, outputs, dependency chains. After it’s been inqueued, sometime later, your constraints have been met. If you have no constraints, it runs right away. If there are constraints, the OS will tell you. Same task executor using a Worker factory to create a Worker. It’s a factory for Workers and you can make your own. You can customize and do things with it After the Worker’s created, we execute it on an executor. This is actually a thing you can customize. We’ll talk more about that, later, as well What if you don’t want to execute something on that executor? What if you’re using RxJava or Coroutine? What if you have your own solution you want to use to run things in the background? This was a request that came up quite a lot when we first released WorkManager So, to do this, we want to provide you an API to let you do work, on your own, and just tell us when it’s done. You want to do async when you’re done. We split it out the Guava team has

worked on this so you don’t need a full dependency for this It’s literally one or two classes now. It’s a feature that can have one or more listeners and those listeners can be envoked on a spec feed executor So using this, we made listenable worker You need to override start work You give us a listable feature You do whatever work you want and when you’re done, set the result on the feature and we’ll be able to listen to it and react to it So the actual threading model, in WorkManager, it goes to the task executor, which uses the Worker factory to create a listen Worker. We call start work on it and we attach a listener so we can listen to whenever you’re done. The Worker class is a simple listenable worker. We have the do work method we talked about We override the start work for you. We create a feature. On the background executor, we execute the work. And we, of course, return the feature So, now we have two classes, Worker and listenable Workers Workers are a simpler class. A class that runs synchronously and on a background thread Listenable runs runs asynchronously on an unspecified background thread. You’re expected to do what you’re finishing there You may to return a listenable feature. If you have access to Guava, you have access to listeners. If you don’t, it is a light-weight implementation we provide in AndroidX concurrent features One of the things that a lot of people are trying — and doing incorrectly with work Workers is they’re trying to do locations If you listen to the Kotlin suspenders talk, they talked about it. Remember that a Worker class is synchronous. If you attach a call-back but return success, your work is already completed. It’s not going to work the way you think it is So, first thing we do here, we’re using a listener Worker, this is the feature we’ll return and do our bookkeeping on. In the start work method, we’ll check to see if we have permissions. If we don’t, we’ll set a failure on the feature Otherwise, what we’ll do is we’ll get that provider’s last location. This is like a feature in GMS core or Google Pay Services world. And then we return to feature. That is the high-level start work In the get location method, we’ll use that task and add a listener to it. If the task is successful, we’ll pass that back with a success status Otherwise, we’ll set an exception. We have addressed the three cases where we want to have a successful or an unsuccessful task or if we don’t have permissions and WorkManager will attach that listener, it’ll listen to the success and failure of the task and do the bookkeeping as necessary All right Let’s talk about operations Sumir mentioned WorkManager uses database as a source of truth When you inqueue or do work, we have to do some bookkeeping These are a database and we have to do them on a background thread. As a result, they’re asynchronous. What if you wanted to do something after the inqueue happened or the cancel happened? You want to make sure they completed before you want to do more stuff? We’ve introduced a new API. Inqueue and cancel have Operations Operation is a very simple interface. It has two methods A get state API, which returns a LiveData. If you attach an observer, you will asea it transitions from an in-progress to a success or failure. The other one returns the feature

type. Remember this API will only return the terminal state of the operation. If you’re attaching a listener, you will get a success or failed and what the exception is and telling you why the failure happened Another question a lot of people have is, when is work stopped, what happens when you stop work on behalf of WorkManager? So, there’s three cases when work is stopped. The first is very simple, your constraints are no longer met You said I neat a network to do this upload task but your network got lost. A second case is that the OS pre-emted your work. The third reason is you canceled your work somewhere else in your app. How do we stop work? There’s a method listener Worker on-stopped. You override this and you get your stop signal We cancel that feature so you can add your own listener and look for that So, this is your — when one of these two things happen for you, this is your signal to be a good citizen and clean up because after this is called, the process may be killed by the OS So, if the OS woke up your app’s process just to run this work, it could actually kill it when it decides that the work should stop and if you happen to return something after this signal, say, you returned a success, we ignored it because as far as we’re concerned, your work has been stopped You can also pull from stoppages in your Worker so you can call the isstopped method. That will tell you whether you’ve been signaled for stopping. So, let’s look at how you can be a good citizen and clean up Let’s say we’re parsing a file asynchronously and you’re doing it in a Worker. You’ve got this input stream so you’re reading a file. In start work, you say parse file. This is doing something asynchronously and you return to feature. Here’s parse file. You’ve got some executor, whatever, a Coroutine, you’re asynchronously doing that You’re opening a file, you’re reading each byte out of the file, doing something with that byte and when you’re done, you set a success because you’re done and you have the necessary tricatch finally after that so you can clean up after youself So, how do we handle when your work gets stopped while this is executing? Let’s say we want to finish what we’re doing, we could easily close that input file stream. Okay. So, what happens now? You’ve done that Let’s go back to the code Well, if you’re in the middle of that read loop and you close a file, it throws an exception The next time you try to read something, fortunately, you’re already handling that exception there. There’s one more case you forgot about here which is, what if the on-stop happens before you open the file? You’re not looking for that because it never got that signal and you’ll read that file because it opened before you tried to close it. You’ll do all this work and how you fix it is use that is-stop method This is a good example of how you would honor the OS’s signal to you that you should stop and be a good citizen So every time you inqueue a method or every time you inqueue a work request, it goes through several transitions. Let’s look at life of a one-time work request. It can be blocked, if it’s blocked on another request or inqueued. Once it is met, it goes into running. Once — depending on the result you return, we’ll take it to one of the terminal states. If the Worker returns success, then it’s — we’ll terminate it with a succeeded state. If it returns a failure, then we’ll mark it as a failure. At any

point in time, while the Worker was in a non-terminating state, if you actually retry, then we’ll apply the back-off policy and retry. So the Worker will go back to the inqueued state If you have a non-terminating state and you call cancel, it’ll end up in cancel Now let’s look at periodic work It’s almost the same. Because it can be chained, there’s no blocked state. It all ends up in the inqueue state. So, whether you succeed or you retry, it’ll go back into the inqueued state. This might seem confusing. If you succeed, it is done. We’ll wait for the next interval. If you fail and ask us to retry, we’ll apply the appropriate back-off policy We’ll tell you this is the second time you’re trying to run it for that last period And, if you mark your work as failed, then we’ll transition it to the fail state. At that point, your periodic work won’t run again. When it’s in a non-terminal state and you cancel it, we’ll mark it as canceled Let’s apply that to life of a chain. Here is the parent of all Workers. So, when you inqueue this chain of work, all descendants are blocked now Constraints are met and it goes into running state. Once it is done, let’s assume you succeeded so it unlocks B and C now and they go into running and for the sake of the argument, let’s assume that B succeeds and C fails. B unlocks D so D goes into the inqueued state. Notice what happens to E, F, and G, they all failed. If a unit gets canceled, all of its descendants are also marked canceled So I’m going to talk about unique work and let’s start with a little question here. What’s wrong with this code? You’ve got an application object in the on-create. The problem here — and I’ve seen this in a few bugs — is that this inqueues periodic work every time your app process starts. That’s probably not what you’re trying to do. You’re trying to set up a sync here. If you call this code every time the app starts, every time you’ve got another thing that’s syncing your code, you really only want one of them. So unique work lets you — if you insert the same key into a database again, do you want to overwrite and ignore what you’re trying to do? That’s what unique work does, it’s a conflict policy for WorkManager. Here’s the syntax Unique is that name, that key Something that uniquely identifies that chain of work Policy is the existing work policy or the conflict policies and then you obviously have your requests So, the existing work policies, there’s three of them. The first one is keep. If you have things in blocked, running or inqueuedinqueued, it will keep them. If the work is finished or not sent, it will inqueue what you sent. The next one is replace It always replaces the work request in the database. If your work is running, it’ll get stopped as I described a few minutes earlier. It cancels the old work and it stops it. A pend is a special one. It appends to that chain of work This is useful if you’re trying to do something, in order, for example, you’re trying to build a messagng app and you’re sending messages in order, you may have a unique chain of work for sending messages and you want to append new messages at the end of it so it’s basically creating a tree for you Sumir mentioned that one of his previous slides on how you can customize WorkManager, so, let’s look at all the things you can do. You can actually specify a worker factory that can be used to use your Workers This is useful in the context of — if you’re using Dagger and you want to inject something,

this is a good place to do that You can specify the default executor that you want all WorkerWorkers to use. You can specify the Login if you want to distinguish between a build and release build and log more information to diagnose your problems and do Job Scheduler parameters, like number of jobs you want us to send to Job Scheduler, the IDs you want us to know in case you’re already using Job Scheduler before If you want to customize WorkManager, then you have to disable the default and add this entry to your man ifest. So now that you’ve disabled it, you need to actually create a new instance of configuration Here, I’m using the configuration building and overwriting it. I can call it to initialize So, make sure you do this in your application on-create Because the system — the operating system can actually envoke job sources on your behalf. WorkManager needs to be initialized Finally, the last thing we want to talk about, before we wrap-up, is some tips for all library developers out there If you’re using WorkManager in your library, you have some special use cases we want to think about. So the general advice we give is because WorkManager’s a single and the application initializes it, as Rahul just showed you, you’re not really in control of what’s there. The default Worker factory creates Workers and listenlistenable Workers. If you need a particular dependency injection or anything else of that sort, you’ll have to have a contract with the app Silo your work with tags. Rahul showed you how to tag your work If you silo all your work, put your prefix or your package name or library name in your tags, you can easily identify all the work that’s yours. You don’t have to worry about other people — other people’s work You can get your work and operate on that. Finally, we do provide the ability for apps to wipe away all work. This is generally for privacy reasons It’s for that sort of critical use case where you have to wipe user data, for some reason So, as a library developer, how do you find out if your work’s been gone from under you. Look at get last cancel all time — sorry, it’s very confusing Okay. Next steps. So, get WorkManager if you haven’t already. For those of you who have, thank you very much We’re up to alpha 11, so there’s three general categories of artifacts, there’s one and KPX and testing support as well These are some helpful links Schedule task with WorkManager is the developer.Android.com There’s the YouTube — on YouTube, there’s the Google I/O 2018 talks which talks about the basics. Some of those APIs have changed a little bit, but it’s still broadly a good thing to read — or to listen to And, also, please file your feedback at our publish issue tracker. Beta is coming, we were told yesterday morning. We have to get back to work [Laughter] Thanks a lot. Please visit all the Jetpack libraries on the web and we’ll be outside for any questions you might have Thanks Thanks [Applause] Everyone, the next session, in this room, will begin at 1:55 p.m. Thank you [Applause]

Hi, everyone. Thank you for joining us for Best Practices

for Themes and Styles And I’m Alan Viverette

We will take about designing themes and styles for your

appplication. The way that designers create mocks. Here’s

the latest iteration of the Material Design theme pallet If you’re not using if for Android yet, you might recognize primary from the Material Theming in the platform. It is like color primary dark. And, when you get a mock from I designer, you may doing a mental mapping, this is going to be my darker color, this is going to be my primary color. It’s important to make sure your designers understands there are canonical atattributes. It can be helpful to push back a little bit and say, let’s call this the primary variance or primary color and it’s great that we all of these pre-designed theme colors with meaningful names and meaningful contrast ratios that have to exist between foreground and background Occasionally, you will get a brand-new color that doesn’t exist anywhere and finding a name for this may be difficult Here we have a purple color that’s lighter than our primary variance and it has contrast against while so we’re going to be displaying white text on top of it. If we want to come up with a name for this, we should find something that can generalize but is self-capturing. If we decide we had a purple theme, now we need a blue theme, we can reuse the name of the color and reuse those constraints So, what are we going to call that? Well, over in the pallet, we have these on color On-primary means this is a foreground color displayed on a primary background and ensure it’s going to meet accessibility ratios. You’ll be able to read the foreground text color against the background. We have secondary, if we have something on the blue color, it would be white. We can generate a new name for the lighter color We’re going to use on-primary That determines the foreground color protection. For background color protection, we want to make sure it contrasts with primary. We can call it primary light, which seems incredibly straightforward and it is. So, you can tell your designer, every time we’re talking about this lighter version of our primary color, let’s refer to it as primary light and it’ll have these constraints If your designer decides we want it to be blue instead of purple, we can continue to use the same constraints and use our semantically-designed color theme. Similarly, we provide common patterns for text appearance. We have headline, overline, body. These are names from where they are going to be used. That determines the pixel size, the weight and the color On the right, we see what that map to. In this case, headline is going to be roboto. However, if we decided we wanted to use, let’s say, comic sans, we wouldn’t have to go through and create a new style everywhere in our application because we do have these names that imply how they’re used Use meaningful name when you’re extracting from your mocks Learn the Material Design attributes. They are at material.io. Use this as a commoncommon language when you’re looking at mocks or looking at something new that has a random gray color in it Make sure it has a name you can use. If you are implementing dark mode, if you attended that talk earlier today, you know this gray needs to turn into a light white because it needs contrast against a certain text

color or background color Use meaningful attribute names They should be more or less self-documenting. Something like primary light has more constraints than it looks like primary color. Go ahead and document these somewhere. Start an internal site you share with your designers to make sure you’re always using a common language when talking about the components, the colors, the reusable texts. That’s a good starting place on how to name them and how to talk about them When you get a mock that says, this is the hex color 4836Ef, push back on that and say, this isn’t a hex color. It has meaning and we need to be able to smoothly-transition from this hex color to a hex color with similar constraints So, now Nick is going to talk a little bit more about what this means in implementation Thank you. Right. So, we talked a lot about supporting different semantically-named values. It can be implemented as theme attributes. What happens if your design changes and all of a sudden, instead of a purple theme, you have a blue theme These semantic names protect you and it’s more wide-spread than you might realize. So, if you want to have areas which can support these kind of theming, there are different ways you can achieve this. One way might be, define different styles. I’m going to set up a style and call that style 1 and then I want to to look different so I’ll give it style 2. The problem with this approach is there’s going to be a lot of duplication and there’s 2 places for you to maintain or bug fix or refactor Using the semantical pointers to describe what it should look like or a theme attribute protects you against this. It might be more work to establish this language and set up your styles to refer back to theme attributes, what it does is it ends up with a single place, a single style, that will refer back to the theme attributes defined for a given theme And the benefits of this is it’s going to duplicate the style And also localizes the modeifications. So that means it you need to change an attribute, you go to that one place where it’s defined rather than have to track it down where it’s leaked out It also has the benefit, I think, of consolidation. How many times have you opened your colors XML files and found 50 shades of similarly-looking colors and you see a mock and you say, okay, I’ll just create another color resource. It protects you against this. You want to condense it down to this small pallet. You have a nice look and feel Basically, this approach really, really helps you with the maintainability of your app. I urge you to prefer theme attributes where possible. If you write code like the top line, the text color should be this color resource, think of it as a code smell. Is this layout, is there a chance this might appear in a different theme? Could it be included in a different area of the application? If so, should I be looking at the bottom form, looking at the question mark syntax, which is how you refer to these theme attributes? So, we talked about the importance of the semantical parts. You can set a theme directly on an activity and these are using components, which is a doc theme or maybe you’re using a night mode. So, this is a theme which will change between dark and light depending on the time of day What happens if you have a screen like this, this is a Google I/O app. Most of these list items are the same but the designed called for some to be light on dark and some dark on light. You can do separate layouts or separating text colors. Both of those basically either leak out the information beyond where you want it to lead to an explosion of more maintenance. Instead, what you probably want to do is look at applying themes at the view

level rather than at the whole activity level. The attribute theme was added in API 21. So, in this, you can set a theme on a view or a view group and apply a different theme to a subsection of your view hiarkry So, in these example, you might say you have a light theme and apply a dark version of it, or vice versa. You can do the same thing in code by using the wrapper. You take the existing theme and it overlays a style on top of it It is overlaid. That means that you have an existing theme and any values from the theme you set on top of are going to be applied on top so you need to be a little bit conscious of this fact. Either you don’t want to overlay a theme which supplies too many values. If I was using material component s light and then doc, you might overwrite too much. You want to make sure the theme you’re overwriting expresses the theme you need You might want to take a look at the theme overlays just to theme the attributes you want such that when it’s overlaid, you get the resulting combination of themes While the context theme wrapper approach looks close to dynamic theming, it’s not. You have to apply a theme which you’ve defined at compile time. You can’t use this to take color values and create a dynamic theme. This is ahead of time thinking So, before you start setting a bunch of theme attributes, it’s important to understand how they’re applied through the platform. We’re going to do a whirlwind tour that occur on screen and your application themes. At any point in your application, it’s good to have a background understanding that you can point to something on the screen and understand the layer direction and theme attributes and styles applied to render it this way on screen If we want to set this color for a single button, how would we do that? Well, let’s dive into the way that this gets resolved at runtime. We have button in XML If you watch the demystifying themes and styles talk, you have a complete understanding of how this works. If you haven’t watched that, go watch it. The button style that you see here is pulled from the theme — the theme of the context in which the button is inflated. So, relevant button-style attribute here at the bottom of the screen Next, where is that button style designed? It is on the material theme there is widget.material button. Where do we find the definition? Over in styles material. So, we can see here, the background is this button default drawable. Right below that bordered ink button style, we have another style. We realize it’s going to be a little bit closer because it provides a color in the button So, let’s dive into the background that’s used, there, to see what gets pulled from our theme In the buttoncolor.XML, it matches up with the drawable names so there’s an easy chain you can follow. We have a shape, it’s a rectangle, it is colored with a tint, which is our button-colored background material. This gets applied to the white color of the shape so it’s got a solid white color here. Let’s dig into the tint It is our color accent. It is named buttoncoloredmaterialXML A very clear line of indirection. So, where does this color accent from come? It’s going to come from whatever exists in our application theme That inherits from material and it will be the default teal So here are all the levels of indirection we’ve looked at Some of the important ones are if we want to change the style for all buttons that get inflated, that’s our button style theme. The button style that we’re getting by default is

widget.materialbutton. We can change that to button.colored if we wanted color buttons everywhere. We can also change our color accent. If we set that in our theme, that gets used everywhere. We’ll see that color everywhere But what we want to do is one button. So, what would happen if we set bet button on our activity? We could see it everywhere. What about in XML? How can we fix that? Well, what if we set color accents on our activity theme, now we’re getting that blue button, but we’re also getting blue switches and everything else. If you do a search over XML files, you’ll see it in a lot of places. We could try setting it in layoutXML. This does absolutely nothing because it’s a theme attribute and you shouldn’t try to set it in Layout KWM XML We’ll create a theme XML and apply that to the button and we’ll get what we wanted So, back to Nick for more implementation Cheers So, I said you should prefer theme attributes where you can But to do so, you kind of need to know what is out there, what exists. Honestly, I don’t have a great answer for you, other than looking through the file — this is from the Android platform or from appcompat or material components. They’re not that long and you can see what’s available. You can look at themes.material and see which theme attributes they set and as such, you are able to reference or overwrite yourselves One note is that you might see that some theme attributes are double-defined. The platform defines an Android color control highlight and then appcompat defines its own. So, which do you use? The answer is if there is one defined in the appcompat, prefer that because it will set the platform one for you and be available for backwards compatibility You can refer to these in code, using something like this and uses KTX to make it more convenient So, so far, we’ve talked about using platform theme attributes, and you absolutely should. But you can also create your own Let’s walk through an example We have two screens, which display very similar layouts. A list of schedule and speaker details. They only differ in the how far with the space on the space and the key line we want to align it to. You need to leave room for the sticky header time things. To accomplish this, we defined our own theme attribute. This is called sessionless keyline. In the different activity themes, we can provide different dimension values for that keyline And then RGS we just have to have a single layout, which references that — that theme attribute using the question mark syntax to vary it without having to maintain it, et cetera Another place that theming comes into handy is drawables. We looked at the platform button from API 21 onwards, all drawable support tint and tint modes. You can also do this in vectors where they support theme attributes for tints, as well as for fills and strokes. So you can use this not just in 21, but in the backwards compatibility library as well. If you need the backwards compatibility, you can use backwards There is an override which lets you set a tint list to be applied, which is something we’ve learned to be extremely handy. It provides different tints and all colors for different states. This is taken from text primary. One of the things I love about colors like this is some of the improvements that arrived in Marshmallow 23, which allowed you to separate out the color and alpha component. This protects you against the explosion of 20 different capacities of black Actually separating out the — kind of the color information from the alpha information allows you to define more specifically what you want Here, it was saying it’s a light screen and the foreground will

be ground. You can say the text will be black and have alphas So you don’t have to define all the combinations, you define the semantically-named things. And then they get combined by the color state lists I’ve cheated here and changed the Android alpha to app alpha because appcompat back ports this to added color state list, but it requires you to use App Alpha The alpha channel of the color and the alpha are combined Don’t do this. If you specify — this is a 50% white text if you don’t speak heck and a 50% alpha. You’ll end up with 20% alpha white. You want to refer to colors with full alphas Like I said, appcompat has this and use resources to get the backwards compatible behavior So, overall, if you apply this theming, you can get a state like this. So, on the left, these look quite similar. On the left, we have the Google I/O. And to retheme it, to fit in with the look and feel with this conference, rather than I/O, this is the diffance. We had to change the semantically-named colors. It ripples outwards, the bottom nav changes, some of the tints on drawables changes. Think about if your product manager comes to you and says, we’re changing all the colors. Wouldn’t you rather have this rather than going through all the XMLs and where is it? You really want to limit the changes to these semantic names So, as a summary of this, really, really, like, theme attribute all the things essentially. Use them as just kind of like protection and you should probably push that semantic system back upwards to your designers so they are giving you values that work with this XML is the preferred syntax or be careful when you’re not writing this and thinking, is this a smell? With your drawables, think about using tints to protect yourself. If all these drawables had been pings instead and we had to rebrand, am I going to have to regenerate all of these? Ignore that, don’t do that. Use tints instead Basically, if every time you use a PNG, think, should this be a PNG. Pretty much the only time you should be using PNG is for matches. So, that’s a summary Protect yourselves and have fun with attributes and styles Cheers [Applause] Hi, everyone. Today, I’m going to be sharing some best practices when using the AndroidX library. I’m going to be taking about preferences and shared preferences. And I’m going to cover how you can use multiple setting screens First some background. What are preferences? The preference library is for interactive screens. All you need to do is find a list of settings to be displayed to the user and it also handles interacting with the device storage so any value the user changes would be uploaded to the device First, the framework preference API. This has been bundled with the first Android framework Since it is part of the framework, any new features and bug fixes we add only make their way to the newer versions of

Android. Given the design has changed, the framework API is themed differently depending on which version of Android. We’re no longer maintaining the framework API and recommend using the AndroidX library. It was the V7 and V14. It with be updated. The library is backwards compatible down to API 14 and uses the same updated material theme This results in a consistent experiences with your users How does it relate to shared preferences, you can have key data. They are used internally to save and retrieve any values but aren’t part of the library We’ll load the simple hierarchy on the right. We have a preference to toggling and one for text So, we’re going to start at the top with a simple activity that acts as a container this should have an appcompat theme. This is the main entry point when uses the preference library All the interesting preferences and configuration will happen in here. This fragment, itself, just wraps a hierarchy of individual preferences, which can be defined in an XML resource or programatically in runtime. We’re going to focus on XML So, the activity, itself, is just a simple container for our fragment. We have fragment boilerplate and show the fragment. The fragment, again, fairly simple. All you need to do is overwrite this and set up the hierarchy. The interesting definition happens in the XML So, this is our XML file. We start with a root preference screen object and this is the main container for the hierarchy. Note that you should also place your preference XML in the XML directary. This is a basic preference, it doesn’t have any widget associated with it and we have three important attributes here. The title and summary are displayed to the user. The key is pretty important. If this preference were to persist any state to the device, then this is the key that the shared preference would use. This key allows you to interact with this preference later on in the lifecycle Now we can add a switch preference compat. This is similar to before, but now we have a switch widget. Whenever the user toggles it, it will go to the key defined here Here’s the hierarchy we’re going to end up here. We’re going to take is step-by-step. I’m going to cover categories to split up complex groups and preferences that open dialogues which allow for more complex configuration I’m going to talk about dynamic summaries and also cover dependencies So, continuing from where we left off before, these are the same preferences we had before, one of these controls syncing some one displays static information about the application. The more we add to this hierarchy, the harder it’s going to be for the user to see what does what. We can set this up in logical subsections. We wrap it with a preference category tag. It adds an accented title above the groups It’s important to set a key for these so it will be a correctly-persisted state. Same as before, same attribute, just displayed slightly differently Next we’re going to add an edit text preference. This preference uses a dialogue to allow persisting a string value when a user taps on this preference, we open a dialogue for you which contains an editable text field. However, this gives us some interesting questions. What do we set for the summary here? Right now, there’s no summary so it’s quite hard for the user to see what the current state is and we’d like to let the user see what they’ve saved

The answer here is to use simple summary provider. This is added recently in the 1.1 alpha release and it’s part of a broad category of things we call dynamic summaries. This simple attribute, when set to true, will mean the preference summary will show the preference or the text set. We have a way for the user to set a sync code and see it automatically. However, it doesn’t make sense for the user to be able to change this field if syncing isn’t enabled. We can use a dependency here to fix that Essentially, setting a dependency allows another preference to control the state of this preference. So, we set the key of the switch prefance compat. Whenever the switch prefance is turned off, it is grayed out and can no longer be interacted with. When it is turned on, it goes back to normal Or hierarchy is almost complete Enable periodic syncing is on, but what does that mean? Have we synced recently? We can use a custom dynamic summary to display when we’ve lost sync, providing more useful context Dynamic summaries are good if you’d like to provide the user with more context. So, in this case, we’d like to tell them when we last synced their device or when you want to display dynamic information. This could be version information or an ID address We can use this to react or do a summary from external state. We switch this. When the preference is checked, when syncing enabled, we want to display the last time we successfully synced. Otherwise, we’re going to say it’s disabled. All we need to do now is set this on the preference So, to do that, we call find-preference. And then we just set the summary. This should be done in oncreate. The summary will be updated based on the constraints we’ve designed I’m going do use separate hierarchies in separate screens A lot of times you’ll want to separate complex hierarchies in separate screens. If you’re already using the framework API, there are some different ways you have structured your separate screens. If you’re starting fresh, you may be wondering what the best way of handling this is. We have our activity at the top, which will internally wrap a fragment, which contains the hierarchy We can consider it to be a screen of settings. We have an activity who loads a setting screen. This looks fine when we have one screen. What if our hierarchy looks like this? We have links to other screens And messages will link to some more specific messages preferences. How does this look like with our architecture? It’s very simple to what we’ve done previously with a single screen The initial setting screen will be compat with a hierarchy. And then the sync-scanning screen will be fragment with a hierarchy and so on for any other screens you have. All we need to do is the final link between the preference. So whenever the user can load the screen. And they tap a preference, we’re going to swap out the screen from underneath Because we’re using preferences, the initial settings hierarchy is going to be as we’ve done before. We have two preferences, one for syncing and one for messages You may want to add an icon here to provide more context to the user. This is just done by defining a drawable with the icon attribute. So this will be something like a drawable directary. So to do this, we use the fragment attribute and

set the class name of the fragment If your fragment is nested in a class, you’ll need to use a dollar sign and that’s it for the hierarchy The activity is similar to before. We should implement this preference. This is called when a user tapped on a preference and allows you to customize anything. There is a default implementation And the fragments are going to be exactly the same as before Again, we overwrite oncreate preferences and that’s really it now. When they tap on the message, the fragment will be automatically displayed to the user So, to wrap some things, we’ve released 1.1 alpha 1, please, if you haven’t already, get it Please file any bugs on issuetracker.Google.com. We’ve updated the Android settings guide. Please check it out for further infermation on some of the things I’ve talked about in this talk and we’re working on template and public samples, demonstrating this library, coming soon For more information on Android Jetpack, you can go to developer.com/developer And, thank you for listening [Applause] Everyone, our next session will begin in just over 10 minutes. Thank you Hey, my name is Cameron Ketcham. I work on the material

design components team and I work out of the New York City

I’m Gautham Sajith and I’m based in San Francisco

We are going to talk about Material Design components. So, quickly, what we’re going to discuss, a brief history of Material Design, what Material Theming is, using Material Design components, the color type and shape subsystems and how to apply these subsystems, as well as our release process and a little bit about contributing. Quickly, just a brief history, Material Design was announced in 2014 and there wasn’t a Material Design library. At I/O, a year later, Google announced the support library, which helped bring a lot of code for certain componentcomponents, including navigation drawer, but there still wasn’t that much This year, we announced Material Theming to have a larger engineering team behind it so we’re working on implementing a lot of the components based on the Material Design spec So Material Theming, what was the original problem with Material Design? Well it was a great initial version of a design system. It fell short with the expression of brand So, here’s an example of an email app and it looks kind of like every other app that use Material Design and it’s hard to tell it’s even an email app, in my opinion. Here’s an example of the kinds of things you can do with Material Theming to make your apps stand out and we’re going to get into those details in a bit So, quickly, how does theming work? Basically, theming is a system that we’ve designed to help you create a unique design for your app. You need to decide on fonts, colors, shapes, et cetera and this is a Material Design sketch plugin that can be used, which can help you create design ideas. Take a look at material.io for more information on that tool These are material theming and they all look quit different and there’s also a lot more of these on material.io Cool, so now let’s talk about how to get started using the material components library So, imagine this scenario, you got this fairly-plain app and your teammate asked you to redesign it. So, you may be familiar with the support library design package, the V 28 version and you can use this However, this is no longer being updated so you should use the AndroidX. One thing to note, you can’t use the com.Android If you want to switch over to AndroidX, there’s a nice refactor tool on the site that’ll help you refactor your app And then the next thing you’ll need to do is use our material themes that correspond to the Appcompat themes. It helps you with default styles you can use across all of our components If you use appcompat.lite, you should have all our attributes and component styles. If you use our components without these defined, you’ll get an error at runtime. If they don’t exist, it will crash at runtime. Use our theme, it’ll give you all the attributes. If you’re not quite ready to switch over to our full theme, you want to get the attributes, you can use the bridge themes and what these bridge themes do is provide you all the attributes but they don’t give you any of the default styles so you can opt in to use our components one by one If you’re extending from a bridge theme and you want to opt in, you would define in your theme and then all of your bottom app bars would get the component style So, now, we’re just going to

talk a little bit about some new components. With Material Theming, we introduced a few new things, such as the bottom app bar. The bottom app bar displays navigation and key actions at the bottom of mobile screens, which are great for people who are one-handed, using their thumb to interact with the device. It uses a coordinator layout to coordinate the motion between a bottom app bar and a floating action button So, here, we just have simple XML for the bottom map bar. A few of the things you can do is set the vertical off-set and set the fab cradle margin, which is the distance between the fab and the bottom app bar and the rounded corner radius, which is the corner where the bottom meets the fab. You can have the bottom app bar hide on scroll and set this alignment mode. It will animate the fab for you And it’s useful if you’re going between different screens If you’re already using a toolbar, it’s super easy to start using the bottom app bar If you’re setting the support action bar, set it for the bottom app bar instead and everything else works the same way. You can use an on-menu click listener directly on the bottom app bar We also have what’s revamped version of the button to make styling much simpler. So, if you just put this material button component in your XML, you’ll get a styled button. If you’re using our full theme, you can use the button tag in your XML and we do custom view inflation where this will inflate into a material button tag and you can see the disabled state on this button and all the states will transfer over. You can set an icon on this button by setting the icon attribute as well as this icon style and this style’s optional, but what it’ll do is it’ll adjust the padding slightly to achieve more balance on the button You can set the outline button to get the hairline button. You can set the background tint of the button by sitting the background tint attribute and provide a color state list You can set some other attributes, such as stroke width, stroke color, corner radius on this button. You can also create just an icon-only button. We’re setting the icon and setting the padding to zero so the icon is centered in the button and we set the content description on this button Since there’s no text, you should set a description You can set the ripple color on the button. If you set a purple ripple on here and apply it to the button, you can do a color state list or hex color here It’s a purple ripple, it’s on top of a green button And these are some of the examples. We have several different styles of chips, text fields, password show and hide functionality and layouts, as well Okay. Now, a little bit about theming. MDC replies on the theming of Android so here’s a quick refresher of how themes and styles work. Anything applied directly to a view in XML will only change the single view. You can also update the style. So, if you set an attribute in a style, changing this here will affect any fews that are using this style If it’s not to define a style or there’s no style set, it’ll go back to the default style. So, here, if you want to change the way a whole group of components look, you can set the default style. And then finally, if that attribute isn’t defined anywhere else, it’ll look in the theme. The way Material Theming works is there’s a set of top-level attributes you should overwrite for tipography, colors, shapes and the default

styles. If you need more fine-grain control, you can hook in, in any of these layers, and change just the color of a single view or the color of all a certain component Here’s an example from our library of the chip. It comes from the fact that other styles, in our library, can reference these same attributes. Here’s an example of a button. They have the same shape appearance, which is the small component shape appearance. If we want to update the look and feel of our app for these small components, all we have to do is update this attribute in one place in our theme and we’ll show you an example in a little bit What are the affects of these attributes? We try to apply theme attributes in a way that would make sense, but it’s definitely possible for you to pick values for different colors that may not look great together. You should check out material.io to see how it’ll react. Another simple solution that you could do is to make a debug theme which sets whacky values and see how things look Here’s the bottom map bar on the material.io site and you can see, there, that the container itself is, like, a surface and the icons are the on-surface And, we’ll talk about which attributes you can modify, as well as things to look at for in the next section So, theming subsystems. We currently have type, color and shape. These are the ones you should tweak in order to theme your app. Hopefully most of you are familiar with text appearances. But we’ve incorporated Material Theming, which using theme attributes, to reference these text appearances. So, here’s an example of a toolbar, which uses the headline six attribute rather than a style directly And here are some copy that uses the body one attribute. These are the type attributes that we’ve defined so if you overwrite any of these in your theme, you can set the style and look of your app Color’s another one and you’re probably familiar with primary color and primary accents. We have a wider range of colors so you have more control. These are the semantic names of the pallet of colors that work with cullerative theming. We have primary, primary veryiants Those are the things you should generally theme to be the stale of your app. There’s also a background surface and error colors. You can style those, but you don’t necessarily have to. And then the on-primary, the on-secondary, those need to be accessible when they’re drawn on top of the other colors On-primary, that will be drawn on top of the primary color. If you have text shown on top of the primary background, it should be the on-primary color These are the color attributes that we’ve defined. You can see that there’s a lot of new ones We tried to reuse some that came from appcompat and we have Android color background that we use, which is just the regular Android version of that attribute Shape is another subsystem that you can theme. And it all happens with material shape drawable. So, we’re adding material shape drawable as the background for buttons, cards, fab, bottom map bar. It works with edge and corner treatments We have edge and corner treatments defined for rounded and cut corner, which is every component you’re going to find You can always create your own, as well So, here’s an example of Kotlin code, which defines a rounded corner, treatment and sets that to the material shape drawable, to apply rounded corners to everything. Here is the XML version, as well. So, if you want to do it in XML, we have shape appearance and it’s similar to text appearance. The attributes, here, are the corner

family and the corner size and this sets it to be a rounded corner with 24Dd radius. You can overwrite individual corners. We are overwriting the top left to be cut and you can do the same thing in XML. One thing to notice is that we’re using a shape appearance overlay here, which is basically the same thing except for we only define the attributes that we want to override. The material button has a shape appearance some here, we’re setting the top right corner to be cut Everything else will be inherited from the style of the material button One key idea of Material Theming is to add mapping. This can help give your app a more consistent look and feel by connecting surfaces through shape. There’s small, medium and large components and these are the attributes you can set in your theme. If you want to restyle all the small components to have a cut right corner, you can do that Here’s an example where, just like I said, overriding the small component style. So, we redefine the small appearance, the small component shape appearance, in the theme, to our style. And here, we’re setting the top-right corner to be cut and we’re also setting the parent here so that will inherit all of the other — the rounded corners for the other parts Shadow is something we want to mention, as well. Native elevation is supported for shapes on Lollipop. For API 21 and up. But we’re back porting shadows to API 15 for both concave and convex shapes for common cases, such as rounded or cut corners, as well as for the bottom map bar because this has the cut-out inside of it. It won’t get native shadow, so we fake the shadow with a gradient Now that we’ve heard about our theming subsystem, how do you apply those to your app? You have this appcompat app, we’ll be building something that looks a little bit like this. When you build your own apps, it will look much more beautiful and cohesive than this. So, first thing you’d have to do is, if you’re using action bar theme, you can switch over to material components theme. We’re using the bridge theme because we want to opt-in to using those one by one. Generally we recommend you switch to the full theme, the regular theme before trying out the bridge theme So, let’s say you set these theme color attributes. Some of the existing ones you know are primary and secondary. There is primary on-secondary. You’ll see this color secondary doesn’t show up anywhere in your app yet, but it will Next thing we want to do is get material buttons. If you set the material button style in your theme, all of your buttons should turn into material buttons when you change the XML tag. If you’re using our full theme, this happens automatically We have a bunch of other default styles we’ve laid out here, all it’s component name, plus style For example, if you would set material card style in your theme. And then we’re going to be applying some attributes to these cards. You can sent card elevation, stroke color and stroke width And then say you wanted to change the base style of all the buttons, you would define your own button style and set the parents of it to outline button and then all of your buttons change into outline buttons We can now apply some shape theming to all of your buttons So, we’re going define the shape appearance and set the right corners to be cut and the left corners to be rounded and set the corner size and now you have

this arrow-shaped button. You can also do this using a shape appearance overlay, since buttons have a rounded corner by default. You don’t have to set it for the left side. You deset what you’re changing and it’ll take effect as normal And then say we wanted to have some icon buttons, you would define this icon button style Set the paddings and minwidths as you want and then apply this to your button directly in the XML, as well as setting that icon in content description and then you have the share icon button instead of that share text button You can also switch over to the bottom map bar. So for this, you’d have to set it in your theme and then remove the top app bar from your XML layout and add this bottom app bar here You can add a floating action button by adding the floating action button to your layout and setting the layout anchor attribute to point to the app bar. This fab has that teal color and that’s because we haven’t set the default floating action button style yet. So, once that’s set, you’ll see it’s using color seg secondary Then we can do some text styling for the content of our cards Say you want all of your text to be color on-surface, we’re going to be using a material theme overlay, which I’ll talk about in just a second. It sets the theme for all the contents of that components. We’re setting it tertiary. So material theme overlay, you might have heard of Android theme, you can style a subsection. You can style a dark-colored toolbar in your app. The shortcoming is it doesn’t work in default style You can’t set Android theme Material Theming attribute is supported by our components and it does work in default styles so you can set this for your components and have it theme — the subviews of your components Lastly, we’ll do some text appearance theming. So, previously, the title was hard-coded text appearance style. And similarly, for the text — note body, as well And then we can apply some styling to this. So, for example, if you change headline six to be comic sans, it should now look like this So, why go through the trouble of doing this? Like, why go through the trouble of using top-level attributes for your style? Generally, we do this because we want to be able to style your entire app using these top-level attributes. Say your teammate said, hey, our brand colors are changing and we want this maroon color instead of these blues we have. You switch the top-color attributes and your whole app is rethemed If you want a dark theme or fake dark theme, you change the color attributes and they should respond appropriately to that Now we’re going to talk about custom components and how you can use some of your styles There’s really nothing magical about the way our components use theming. It’s all just basic Android theming, so you can use it in your components, as well You just have to create a default style and pass it into your constructer. So, let’s go through that. Here we have a definition of a theme and some attributes. Here, we’re creating a default style attribute and setting it in our theme so we have my custom view style and we’re setting it to this widget.mycustomview style So, this will mean that any components that use this mycustomview will use this style by default You also can create a styleable, which holds a few different attributes. And then you just need to use these in the constructer. Here’s an example for a view. Here, we pass in the default style, which we created previously. And, we

pass this in here so that it can pick up that default style if nothing else is set. And then, raising attributes and pass in the styleable that we just created, as well as the one passed into the constructer and a fall-back style as a last resort for finding attribute and read those in. That’s basically how our components work. So, you can definitely do it yourself, as well And also, extend the systems for your use cases. Like, if you have the need for more attributes in some case, you can definitely add those in. It might be a little bit more work on your part because you’ll have to update styles for all of the components you’re using since our components aren’t going to be referencing them. But if you need if, you can definitely do that Here’s an example. Just like an attribute. Create it and define it in your theme and reference it in styles or elsewhere Now, a little bit about our process. We’ve had a few releases. The 1.0 went out — was cut on July 20th and it’s been a little while. But now with the Android Jetpack re refactor finish, we can release more frequently so we’re trying to ramp up our releases and we cut 1.1 alpha 1 October 31s t and we’re trying to do this more frequently. There was type theming, color theming and dark theming, plus lots of bug fixes and performance improvements In the upcoming releases, there will be shape theming. 1.1 alpha, the shape theming subsystem exists, but none of the components are actually responding to those themed attributes yet. But with the next release, it should We also updated some styling for dialogues, bottom sheet, menus, those sorts of things are all coming As far as contribuing and filing issues, GitHub is where it is Go on GitHub and you can take a look at all our code. It’s open source. And also check — you can check GitHub for instructions on how to submit bug reports. We’re taking bug reportess at issuetracking.Google. But, we’re looking at different ways to make it more obviiously what we’re working on and trying to integrate more with the community And here’s a few more resources Material.io site is great, especially the Android section Definitely check us out on Discord if you’re interested in chatting with us or are interested in helping us have an idea for anything. Come and chat with us. We have a tag on Stack Overflow, so if you have questions about implementation, you can ask something there, we’re watching that and we’ll respond. And then we have a few codelabs, you can find the link to those codelabs on this GitHub page And, that’s pretty much it Thanks for coming. We’re going to be available for questions and answers at the break that’s happening now Thank you [Applause] [Applause] Hi, everyone. My name is Ian

Lake. I’m a developer on the Android team. And I work on

quite a few projects, but most notably the Navigation

Architecture Component, as well as fragments and the AndroidX

artifact and loaders. And today, I want to talk to you

about single activity, why, when and how. And really try to

share the best practices from the Android treme and from the

Architecture Component team on what actually is going on in

this world. There’s been a lot of questions, way back, from

2014, 16 and even here in 2018, so we’re here, today, to kind of talk over all of those wonderful things that make up what are activities Activities are really a component ant, at the same level of content providers, broadcast receives and they are the UI-facing pieces of your app So when the Android framework goes to start your application from a launch icon or an app shortcut or what we see when you’re doing multi-window, those are all activities, right? So they are the entry points into apps. When the user goes to launch your app, they’re launching an activity And, we had a very interest quote from Diane Hackborn back in 2016, once we’ve gotten into this entry point, we really don’t care how you organize the flow inside. This was 2016 and I think it was controversial, I guess, in 2016. It had 77 comments on Google+, all right? [Laughter] A lot of people were very enthusiastic about this post Well, what does it mean? Well, what I think it means is that the framework shouldn’t care The framework shouldn’t care about your application’s architecture. It needs to provide the hooks needed for the Android framework to start your application. But, you should probably care about the architecture of your app and that’s why you’re all here today and I love having you here So, the biggest problem is that you really don’t know what activity’s actually going to do So, what’s the default animation for an activity? It depends on the version of Android, what manufacturer you’re on and what themes the user has selected Right. So, similarly, we had property animations added in API 11 and they’re much superior to view animations. And the thing is, is that while these new things become possible on new versions of Android, they’re not always applied to everything and things like activities, they don’t support property animations, at all, even today And even if we were to add them, in the next version of Android, maybe the letter after P, we wouldn’t be able to backport them because they’re part of the framework Thinking about all these things it’s like, well, okay, what should an activity be used for? Why do we even have activities? They’re useful as this entry point and beyond that, you’re in your realm of what your app needs to do and you don’t necessarily need to rely on activities being the thing that you have to work with So, let’s take an example We’re calling start activity and we have to use activitycompat because we want to do a shared element transition. We say, oh, we want to have this one element shared. Well what do APIs work on? It depends on what you mean by, work. It launches an activity, that’s true. It’s only going to do a share transition on newer editions, 21+. It technically works, you’re saving some API checks But really, this isn’t the prettiest code to look at. Are there any hidden gotchas? If

you tested on an older version of Android, are you actually going to get the same experience? In this example, I actually ran into this and I was like, oh, things are fading in and out. You need to exclude things like the status bar and navigation bar, otherwise they’ll flicker and I was like, well, okay, well that’s fun. I wouldn’t have ever known that unless I tried it once and I tried it on all a whole bunch of have of devices. There are a lot of hiten gotchas you can’t control Another example where we have different activities and it’s its own component. If you have two and you want to share data between them, there isn’t a scope for that. It is served by services. You want a shared scope within a couple of components So, this is the structure that Android provides, but it’s maybe not the one you actually want to use. What you actually want is you want to build the layering you needs. We can have multiple destinations within an activity and share information across each of these destinations by using the activity scope as an actual useful element now. So, for example, you could have a shared view element, a ViewModel that both destinations talk to One destination could put data in and one could observe changes to that data. You don’t need to work at the application scope level for this to work So, I mentioned this word, destination. So, what is a destination? Well, really, it’s just a subsection of your UI So, for most destinations, they’re going to take over the majority of your screen Right Like, when you move from screen to the next screen in your app, it’s going to change the vast majority of your screen. Maybe you have global navigation, like a bottom nav. The rest of this is all in a destination. So, the subsection of your UI, we have a word for this called a fragment. But a fragment’s one implementation of this idea of having separate destinations for each screen in your app And really, this fragment is serving as the view controller, right. The thing that isn’t a view itself, but something that owns and changes those views, which are really more about display All right. So, really, the activity, instead of owning all of this business logic and things like that, is really as small as physically possible and working on that shared UI that’s shared across all destinations So, when we’re thinking about this, like, if we’re moving from this activity world to a destination world, we want to make that world as easy as possible, otherwise, why would we move? We focused on two things. One was the global UI kind of thing. Like, how can we make that part easy? It’s something that every app has the same kind of patterns and we don’t want that to be something that takes a lot of effort to do. Also, the navigating between destinations, right Activity, activitycompat thing, can we make that even easier? We started the Navigation Architecture Component and reintroduced it to you all at I/O. It is still in alpha right now and we’re looking to fill out all the feature gaps before taking it to 1.0 here soon But really what this allows us to do is take a super simple activity like this, set content view, we’ll set an action bar because that’s a thing, right? And, we want to make this smart but we still want it to fit on this one code slide. So, some of this is we need a nav controller. It knows how your app works via a navigation graph. We can get one. We’re using Kotlin here and call

findnavcontroller. We’re giving it the ID of a nav host fragment. It is that part of your UI that’s going to change when’ ever you change destinations. We’ll add an app bar configuration. This controls the up action and what needs to happen when you move up from a destination. And how do we hook that up? We have a nice one-liner that says set up the action bar, gives it a nav controller and an app bar configuration Now because we’re using a drawer layout here in our app bar configuration, we also want to open and shut the drawer when you hit the button. We’ll call navigate up in our support navigate up. We’ve set up our whole action bar and now it changes titles as our destination changes. We’re good. If we want to add the navigation view so we can click on the side nav, that’s one line. We can do this all because the nav controller knows about our destinations in our app So, then how do we actually do navigate actions if we’re not doing fancy one-liner stuff? We can get a nav controller from anywhere. It’s even easier from a fragment, we can do findnavcontroller and we’ve built a Kotlin extension for this. Any view that’s created by any fragment in your navigation graph can call find So, you have this reference to it from basically anywhere And, we really tried to think, like, all right, well, if you have arguments to something, how do we make this nice? So, we built a Gradle plugin We generate a directions object, which has a nice, simple show profile method, which gives you a directions object with typesafe arguments you define in your navigation graph and then you just call to navigate So, this makes it a lot easier but we can go a lot farther with navigation. Has any one ever built an intent filter before? Deep-linking in your app? Has anyone enjoyed that experience? [Laughter] Great! One person enjoyed that experience. This is what the Android framework knows. It knows, I can parse an intent filter and start an activity But in so often times, that’s not quite enough. You need to go a little bit farther. So what we’ve done, in navigation, is for any one of your fragments, any destination in your graph, you can add a deep link. It’s a simple one-liner and you can add arguments right here and we’ll parse those out for query parameters and give them to you as arguments to your destination. Because no one likes writing intent filters, we’ll generate the intent filters for you. We added this to manifest merger to generate that for you So, all this layering helps us build nicer APIs. But, it also makes it easier to test your application. Right. If you’re testing at the activity level, all of a sudden, that means, okay, well, how do I test, start activity actually did the right intent and we have to build extra testing frameworks on top of testing frameworks to mockup these things. If we’re moving into a single activity model, we want to test all those things We want that to be easy to test So, rule number one for testing things at the destination level is, don’t test at the destination level. It’s really the number one thing with testing, right, is making things nice and separate and extracting some of that business logic out of a destination and into something you can test in isolation. Right. So example, a ViewModel is a great place because you can test it in isolation. We have a ViewModel providerprovider factory where you can inject it and test it separate from your UI. But that doesn’t mean you don’t want to test any of your UI stuff at all. Right We have Espresso test for a reason. We want to make sure all parts of our app work well and are testable So, how can we do this? So, last — this Monday, we released

fragment 1.1, the first alpha And with this became a new artifact called fragment testing, which is about six years overdue [Laughter] And it’s really around being able to test your AndroidX fragments in isolation. Right Separate from an activity Separate frem everything else and being able to test and verify that that fragment is doing the right thing. Super useful for Epress so test. Your business lodge, separate. Your UI is still something that we want to verify is correct Now, the nice part about this, it’s called fragment scenario because it’s built on activity scenario, which is part of the AndroidX testing team and the testing team was instrumental in getting fragments out there But the best part about this whole scenario is that it works both on instrumentation tests, tests on your actual device and on robo electric. You get one test framework that works on both of these. Really exciting opportunity and something that now you can test with fragments So, what does this look like? Let’s say we want to test our profile fragment. We did a fake user ID here and we call launch fragment in container. That’s it. This one line has both created an empty activity, added a fragment to it and waited for it to be resumed and now it’s ready. You can now use this fragment. If you want to call onfragment and run some code and say is the fragment in the right state, great, you can do that Here, we’re going to see if it is what we think they are. We passed a user ID, we can use the ARGs class and say, is the user ID equal to the user ID we passed in? You can see, you can run any logic, any method on your fragment right from here or we run Espresso OE test. When we click the subscribe button, does it change the text to subscribed? Does it do its thing? We can do this with that one line of launch fragment in container For Java users, it’ll be fragment scenario. They make it nicer for you guys But, you don’t test a fragment in isolation because, you know, fragments do talk to other fragments, right. I work on navigation, so there’s that other bit of testing how can we test the links between different destinations, between different fragments? The nice part, here, that we have, because we’re using these higher-level components, and not something like activity, is we have a mockable layer. Right. One of the things that we found, which building navigation is most companies, once they got to a certain point and they’re like, well, we should add testing They added navigator to mock out the start activity calls. That layer is handled for you. What we can do, in our activities, is just mock out that nav controller and confirm that, yes, you’re calling the right navigate calls Here, we have our profile fragment again and it’s getting our user ID and what we want to test is this on view subscribers button. We click this and it’s doing something complicated in the fragment. How are we going to test this? It’s calling navigate. How can we make sure this is actually doing what we want it to do? Well, it’s pretty easy. We can do our scenario thing just the same, launch fragment. And now we can mock out our nav controller and now you call onfragment and what we’re doing here is actually just creating our own nav controller. Like, there’s no nav host here. But we can just inject one. This is what nav host fragment is doing under the covers. It’s calling set nav controller on a view. Now what we’ve done is from this fragments point of view, it has a navigation controller. All

those nav controller calls that normally you’d have to inject something, now it just works They’re in there. And now we can just run Espresso tests and click on the subscribers view button. We can use them also in our tests. And because they implement equals, we can just do a simple verify and say, verify Did you actually navigate to where we think you’re navigating? Even if there’s a lot of parameters in there, we can now just verify and this makes it so much easier to test those interconnections between each destination So, nav controller’s kind of a special thing. So many other things aren’t a service locator kind of pattern. We need to inject in those dependancies and this is another one of those, like, six years too late kind of a thing But, we’re finally working on it So, there’s a class in Android P called app component factors that allows you to construct activity all via dependency injection. You get a chance of caller the constructer instead of the system calling it. Same thing here with fragments. Now you can do conSTRUTH structer into fragments. You can use a fragment factory So, this is really useful, also, for cases where your fragment was, like, casting your activity to something. I know we probably still have a template that does this. We’ll fix that And, there’s a lot of ways where really want to inject in all of those external dependancies so we can test in isolation and fragment works great with our fragment scenario We know how to test a ViewModel, right. It’s just an object, it has a real method called subscribe. Really, we want to test our fragment. And our fragment has an onsubscribe fragment and it does its thing How do we get this ViewModel? Well, we can inject the factory itself, inject the ViewModel factory. Here we’re using the by ViewModels, a property that does all that ViewModel providers of kind of stuff for you But, we now have a fragment that we’ve injected something, but then we still need to test, like, okay, did it actually call subscribe? So, we can build a navigation activity. This is what it’s going to look like in real life Right. We’re going to inject our ViewModel factory and then because code is hard and I wanted to write things on slides, I built a helper class call initializer and you call add initializer for each fragment and we call that method to construct. So, a little bit of magic. There’s a link here if you want to check it out We’re looking at trying to integrate this more deeply into the library Once you’ve called this fragment factory, it creates a profile fragment. It’s going to use this constructer and pass in our ViewModel factory. Great. So, our activity looks fine. But, our tests, how does that look? We create a mock of our profile ViewModel and then we can set up a factory for it and then again, kind of use a fragment factory here that, again, does the same type of thing where we’re passing in our mock ViewModel factry and our scenario looks the same. We add it in and instead of just the argurements, also the fragment factory Now we can do our same thing on view, perform the click and then verify that, yes, our mocked ViewModel did the subscribe call. We have a testable fragment, a testable ViewModel We have a testable thing Now, we are looking at some improvements to this API because, you know, we want to

make this even easier. So, in this case, because we know your constructing a profile fragment, we want to change this into something that looks like this Where you can say launch and then give it a method saying, oh, like, you launched this fragment and specifically give it the constructed-out instance of your fragment so you don’t have to actually know that it’s using a fragment factory on under the hood There are a few cases where you might think, oh, man, maybe I do need multiple activities. And, there’s got to be reasons to use multiple activities besides just momentum. Right. I understand that a lot of apps, if you have multiple activities right now, this isn’t actually an easy sell. Right. So, there are a few cases where even, today, we do recommend using multiple activities. Not a lot though So, what I’d like to say is, you don’t actually need multiple activities. What you need are multiple tasks. So, what are tasks? Tasks are actually the thing that users are actually interacting with. So, a task is a stack of activities and each task has a backstack. So, in your overview menu here, each one of these entries isn’t just an activity. It’s actually a whole task stack, right. So you’re only just seeing the top most activity of that stack. So each element here is a stack Right. When you’re doing split-screen multi-window, that’s two tasks side-by-side Right. On Chrome OS devices, things that support floating multi-window, each one of these tasks is a window. One to one between windows and tasks. Not activities ties and windows, tasks and windows So, launching a new task on one of these Chrome OS devices gives you a new window. Right. So, your app, maybe it doesn’t need multiple activities, but maybe it wants multiple windows Right. So, this is the case where, yes, you need to use activities under the hood, each one of these tasks is going to be a separate activity. But, you may not use some of the other things, such as a stack of activities in one task. So, what does this actually look like? A lot of this is that there are a lot of different ways of saying new task. Right Has anyone looked at all those wonderful launch mode flags and all that fun? Yeah. How many people of you are still sane? Okay. Well, I’ll say that there were a lot of good flags out there, in Android 1 [Laughter] They were great back in Android 1. In today, in 2018, they’re maybe not the best thing to use What you actually want to use is document launch mode. Document launch mode was added, actually, in API 21. If you’re thinking about pre-API 21 first, what are you doing? And, second, probably try and steer aware from hackie solutions. Maybe it’s just not worth it for those users. But try and avoid things like launch mode flags and task affinity and those types of things because while the framework does honor those, it maybe doesn’t honor them in the way you want them to honor it There’s certainly very different types of thing. With document launch mode, there’s multi-tasking, if you can have multiple tasks, you can multiple windows. You have multiple entries in your overview screen So the first way of doing multi-tasking is into existing Into existing means whenever I launch this activity, that activity has its own task Every time you launch this activity, it has its own task But if we have already launched that task, don’t create a second and a third copy. This is good for documents, conversations and things someone might want to

side-by-side compare. They’re not going to exit out of one doc, open another one and copy it there. It’s taking the multi-tasking model that is Android and making it so your app actually gets to use this Now of course, the into existing assumes you have some notion of uniqueness. It does assume from an intent fitter equals point of view, if you’re using the data UI on your activity, that there is some sort of unique ID, a conversation ID, a document ID, something to uniquely-define that task One great example is Google Docs. It launches it in another task. You can load them up, side-by-side on a phone. Two different windows on a Chrome OS device. And it just works Even though it’s one app, it can have multiple windows and really allow a different level of multi-tasking between different things So another big one is creating new content. So new content’s a little different because there’s not really any unique ID but you want that multi-tasking behavior are you can reference existing material while you’re creating something new. The always flag is similar to into existing, but it always creates something new It’s like self-descriptive names. We can do this, guys It allows you to do multiple things at one. One example is Gmail, it uses this kind of mode when you create a new email This allows you to create a new email and reference your existing email at the same time It’s magic, right? This is the equivalents, on mobile, of when you do it on a web and it pops up a little mole that’s separate from the other one. You still need that other material as reference On a phone or an a tablet, it looks slightly different. The other case is picture-in-picture, it has two entirely separate modes. One is using a separate task. Right So, this would be a separate activity, just for your playback. So, this is really common on Android TV. TV uses this approach so you can actually put things into picture-in-picture mode and browse through other movies So, in this mode, it’s very much that you have a specific picture-in picture button in your UI. The other mode is using just a single task, one activity. You don’t need anything at all. This is Duo and Google Maps where your whole task is becoming the picture-in-picture activity Right. So, when would you want to choose one or the other? It’s really this case where once I’m in picture-in-picture mode, if they were to click my launcher icon, what would happen? Because the launcher icon always launches the default task of your app. So, in Duo’s case, where they only have one task, when you launch that Duo from your launcher icon, it’s just going to pop open the picture-in-picture. Because it doesn’t make sense to have multiple conversations going at the same time. You’re never going to replace one with the other. You’re never going to continue to reference something even though something is already going. That’s kind of the differentiator here. Do you want to browse picture-in-picture that the same time. If you do want to, yes, you’re using the Android framework and they need to position those separately Separate tasks. Separate activitiesactivities But, that’s kind of it. The one thing I didn’t mention are things like instant apps Instant apps kind of works at the activity level. Right. You call start-activity. But there’s actually some really exciting things that are being worked on by the Play team. I think there was a talk here at Android Dev Summit. A lot of it is around the instance experience for your App Bundle, making your whole app instant and also dynamic feature modules. These are really interesting ways of adding things on to the thing, that

don’t require a specific app architecture to implement. We can actually do more things with this For the instant experience, it’s added equals means true. They can try your entire app, your entire base module totally instant and this works really well with things like app links So those deep links that I said you could add to any destination, you can also make them into app links by adding the auto verify equals true When someone launches your deep link on the web, they’re going to open up your instant app experience and download that whole base module for you and your whole navigation graph is already there, ready to go But, this doesants work if your app is too large so you want to dynamically deliver things that are not used very often or rather big things. That’s what dynamic feature modules are all about About being able to download them on-demand. The interesting thing about dynamic feature modules is you’re adding classes. You don’t need to add activities. You can add just destinations, just the number of fragments. In this case, you can add new destinations, on-demand. Just because you’ve built out an XML file, each one of these dynamic feature modules can add their own navigation graph. So, this means that we’re not tied to separate activities. We can now actually still use one activity Now, there’s still more to be done here, both on the Play side and on the navigation side. But we want to make this really easy for developers to use. So, what we want to get to is where you can add something to your navigation graph with a feature tag, just like you’d add a fragment tag and when you navigate to this destination, that’s actually going to do all of the downloading and making your feature module available from whatever your split name is. So, that’s the world we want to get into where you can use a single activity. Where you can use a lot of the useful things, like deep-linking in navigation, without contorting your app architecture So, I’d really like to end this with one note. A lot of you have existing apps that have very different kind of experiences and I’d like to say, do what’s right for your app. I think single activity’s great I was writing a new activity, it would also be single activity but I realize that doing and saying, hey, let’s rip the whole app apart, is sometimes a hard sell Some of them don’t like your current app. So maybe you’ll actually get some, yeah, okay, good for it. Really depends on your own experiencement if you find yourself contorting your own experience and it’s not making sense to you, don’t do it Right. If something is working, that’s good. Keep it working Right. But if you’re finding you’re running into issues, you’re having inconsistent behavior or you want to do share ViewModel, maybe that’s the time to think about moving toward a single activity Thank you. Q&A outside. Really appreciate you all coming [Applause] Everyone, the next session, in this room, will begin in 10 minutes. Thank you [Applause]

Hello. And, welcome to the last session of Android Dev

Summit, over the ultimate, I think. The is called Get

Animated. I’m Nick Butcher I’m Doris Liu. I’m responsible for Android API I’m Nicolas Roard John Hoford, working on MotionLayout, and design tools Great. So, let’s get started So, Android has always had animation APIs. The number of APIs has grown as the system has grown and become kind of more fully-featured. There are a variety of different APIs for different situations that have been added over the different API releases, as well as to the new support libraries, like AndroidX But, sometimes, we hear that the variety, the range of animation systems can be overwhelming That you don’t know which one to reach for or which is the best for a certain use case. So our goal is to give you an overview, tell you what they’re good for, what they might not be good for and give you there confidence for what to reach for. We’re going to spend more time on MotionLayout, as well First up is Android’s oldest and original animation API, which is Android view animation. I would urge you to consider it deprecated. It’s not actually deprecatedeprecated. But maybe just think of it in that way So, this, like, I say, an older animation API, was kind of — runs in a certain phase of the system. Most views have a measure layout and a draw Because the animations only run in the draw pass, it means that we can’t do certain things like deferring a rendering when we don’t need it. It also leads to certain things to where because only the animation is only applied the draw pass, maybe you’ve animated a button, the views haven’t challenge. They only exist with the viewing draw system basically, consider it deprecateddeprecated. It belongs in a MUSEUM [Laughter] I’d say deprecated except there is one single use case and that is when you’re doing window animations. When a new activity launches, this API only accepts this type of window animation because it existed from API 1 But also because these window animations have to state all the information to perform the animation. The fact that runs in the draw pass is useful That allows it to define certain things like, here, we’re seeing a wide animation, 10% of the y position. Because it’s guaranteed to be measured, this can be useful The only other place is when you’re doing fragment transactions. You can supply this Android view animation But the app accepts the newer Android animator so I urge you to use the newer one if you can So, that was view animations, basically only really use it for wind oanimations or if you need to rely on that part Otherwise, think it’s deprecated Next up. Animator All right. Didn’t change Oops. All right. So, Nick has talked about view animation, now let’s take a look at the new animator that was introduced in API 11. So, the new animator API’s is much more versatile because it allows you to animate more than view property. You can even animate any value, not necessarily associated with any property at all, using the value

animator API And since the introduction of animator, we’ve built a bunch of higher-level animator constructs, such as animator drawable, transition and the default item animator in RecyclerView People always ask me, between animation and animator, which animation API should I use? And the answer is, definitely the animator API. Because it’s just much more capable. And in this section, we’re going to look at a few animators. We’re going to look at value animators and object animator, which not only animates the value, but can assess that value. We’re going to look at animator set. And then, we’re also going to take a look at the view property animator. It is not an animator, but backed by a value animator. We’ll talk a little bit more about that in a minute And then, also, we’re going to look at property values holder, which you can use in conjunction with value animator. Here’s an interesting animation with a juggling man. That can be achieved with the animator drawable, which Nick will talk about in the next section. But now let’s look past that and on top of this little man, there are texts being animated in and out. So, in order to achieve that, we can simply create an object animator to animator The alpha property of this view, pretty straightforward. I’m supplying an alpha string and that is a bad idea because when a property string is being passed to the object animator, we have to prefix that string with a set and get to use reflection to find the setter and getter in the target object’s class and that’s more costly. What we recommend, instead, is using this property object. It is introduced in API 14. Along with a bunch of other properties. What happens is whenever the animation value gets updated, the set value will be called and from there, the set alpha will be called on the view. Must more efficient than reflection If we take a closer look at this animation, we can see that the text blows up, so there are three properties being animated The alpha scale X and scale y Here’s how we can do that. We can create three property value holders, one for each property and then we can specify the start value and end value and once we have all these property value holders defined, we can set this on the object animator Then the object animator can drive the change of the property values One caveat is when you use multiple property value holders on one object animator, you are essentially animating all these properties with the same in turpulator, using the same duration on the same object. A lot of times, we want to animate scale X and scale y simultaneously, that’s what you need. If you want to define that in XML with the property values holder, it looks pretty straightforward If you take a look at the bottom of this animation, there’s a button fading in. To coordinate these different animations together, we can create an animator set and then with the — with the Play method, it would return a building and we want to play the fade-in after the fade-out. So — and then, while the text is fitting in, we also want to blow it up so we’re going to play the fade-in with the scale animation and then we want to play all the text animations before the button fades in So, that’s pretty straightforward API and powerful, too Now we’ve seen how we can animate different properties unconjunction with object animator. If they happen to be view properties, you can call this to create a view property

animator and then there are a bunch of methods for various properties and then you set an end value and optionly, you can set an in turpulator and stop It doesn’t get more beautiful and concise than this View property is backed by a value animator. It’s not an animator so you can’t really coordinate with the other types of animators. You can’t reverse it or repeat it. Some people — some people ask me, is view property animator as efficient as object animator? I can assure you, it’s actually slightly more efficient than object animator. The reason for that, is view property animator has been optimized for animating view properties and it ensures that for all the view propties, there’s one pass of validation gets triggered. Whereas if you use object animator to animate various properties, each property change is going to trigger its own set of validation pass View property animator is more for fire and forget kind of use case where you start animation and just forget about it Now, you might have seen this animation before, in the previous slides. Did you notice there’s three little dots animating at the end of the text? And these little dots are not really a property for the text view. So, here, we’re going to create a value animator to animate the number of dots We’re going to type an integer-type. There’s a repeat count. And with value animator, you almost always want to use an update listener because value animator is going to animate on its own. So, here, with value — with the update listener, we’re going to read the value out of the value animator and use it as the number of dots we want to show And then we’re going to have a spanable string from the text view. We’re going to set a span for the — we’re going to set a transparent color span on — rather on the dots that shouldn’t be showing. And — which with each animation update, we will update the number of dots that should be showing and then correspondingly, change the range to hide the dots that we want to not show So, to recap, when should we use what kind of animator? Object animator is kind of this all-purpose animator that, as long as you have a property you want to animate, you can use that. Value animator is for animating a more customized kind of animation where you want to animate this value and then use that value to apply it to something else in your UI. View property animator is the best use when you have multiple view properties that you need to animate simultaneously on the same view and because you can’t really coordinate this view property animator with anything else, it’s only good it for the fire and forget use case And then property values holders, with property values holder, you can define multiple properties and make them using an object animator. The nice thing about property values holder is that it not only allows you to animate multiple properties simultaneously because it’s really being set on the object animator, you can then coordinate that or seek or reverse, so it’s more powerful Animator set, you have multiple animations you want to coordinate, animator set would be a good choice Thank you very much. Next up, we have animated vector drawable. These are great for doing graphic animations like the wonderful icons you see in the Google Fit appplication. It basically connects together a vector drawable to one or multiple object animators and runs animations on them. It has a very kind of small focused API, it basically implements the animator. You can get a drawable like this and call

start. It is great for, like, performance critical and vector graphic information, especially where drawable was reimplemented in code. Even if you’re doing the UI thread, it will keep playing. There is more time for you to do your code rather than running the animation code When you need to animate icons or animate graphics, when it needs to be this fire and forget. You can’t seek through it. You can’t control the progress for it. I urge you to look at Kirye drawable. It is good for anything that’s performance critical Now, physics animation. Who doesn’t love physics? It is perfect for a highly-interactive use case where you have lots of gestures going on and you want to carry on that momentum of that gesture into a UI to create this sense of continuity Because when they allow gestures in flight, you could then potentially interrupt the existing ongoing animation. I’m sure you’ve seen animations where you want the animation — you want the view to move from one location to the other and then there’s just some from the users and the ending location would have changed. And in this case, if you use physic space animation, that would simply change some physics force and then as a result, the course correction would be really smooth So, here, I have an example of this little bubble with my cat’s picture on it. And it’s in an application overlay window so it sits on top of other applications. And in this case, that is the beautiful Timely app. My goal is, is I drag this little bubble around. When I let go, it should rest on either side of the screen and — so to achieve this, we obviously need to start with a listener and use velocity listener to track the movement and track the positions and in the subsequent events, we’ll need to calculate how much your finger has moved since that down event and update the bubble’s position accordingly and then when there’s an action up, that’s where the interesting thing comes up. We’re going to calculate the velocity and then here, for simplification, for the demo, we’re just going to say, when the velocity is greater than zero, we’re going to move to the right side of the screen. Otherwise, left side Now that we have the final position where we want the bubble to rest on, we can create a string animation. That is a custom property, which I will explain in the next slide Before we start the animation, we also want to set the start velocity and this is critical to ensure that that transition from gesture to the animation is seamless So, this is my custom property and the whole point of this custom property is really just to associate the animation value with the position of that bubble. Whenever the animation value changes, we get this — we get this set value call. We’re then going to set the animation value on to the layout params.X because it is animating in an application overview window and have window manager update view layout to reflect that change and similarly, in get value, we’re just going to return the layout params.X Thank you. Next up is the transitions API. Now, transitions are about looking at two different layout states and saying what has changed between between them. Really, you can think of transitions as a factory. Awhile ago, I talked about how it’s great for doing things like this, two different constraint sets and using transition manager. I think this is

better-solved MotionLayout. I wouldn’t consider it is good for that You call this and make changes to the view hierarchy and magic happens. It looks at the two different states of the UI, works out what’s changed, creates an animator. There’s an overlay where you can control those transition. What I love about transitions is what it does to the code base. Here’s a change where I moved it out of the view layer into transitions Sometimes it can look gnarly like this. Pre-draw listeners and poking around to the view hierarchy. By moving it to transitions, we move it to this declarative architecture. It is composed with some of the transitions in a more composable manner. Yet, you might have to write some transitions youself But, that code ends up being much more — I don’t know — nicer to work with and much more focused and found it like a really good change to the codebase Transitions, which should you use them? For me, there’s one strong use case which is shared It’s pretty much the only thing you can use to achieve this unless you go super custom There’s actually two transitions going on here. There’s the shared element between the 2 AK activities and then there’s a window content transition. When the window launches or exits, run these animations on the content. When the viewer arrives, the rest of the content animates upwards So, when should you use transition API? Shared element elements, for me. Also, if you are looking to modularize and compose your animation code, transitions can be helpful. As well as simple transitions, using the begin delay method MotionLayouts All right. So far we’ve been talking about coding. It’s super powerful. The APIs are really, really complete. On 24 the other hand, it’s quite time-consuming. What can we do to help that? We want to make you more productive, let you iterate faster. We want to make the motion design a lot more accessible. So one thing that we introduced is the helpers object. And in fact, helpers object is something that you’ve been using. We used for guidelines. Not really part of your view, your hierarchy in the sense that it doesn’t show up on screen but they are here to help you create those layouts. To bring additional concepts to make it easier. In 2.0, we exposed them so you can, yourself, create helpers just by narrating the class. It’s a way of doing code and putting into a helper, we support the user, so it’s easy to add and you can think about it as a way of tagging with a specific behavior. In the case of animation, that’s really nice because, you know, you get the code. You have your helper built and we have all the wealth of the Android animation APIs and you can do stuff like that Right. For example, you know, pretty well-known animation The only thing I really needed to do here is define this piece of code and really what I’m talking about — okay. What — what I only need to do here is this code that you see on the screen, I’m simply calling. I’m not reinventing the wheel here I’m not coming up with a new way. But that’s the only thing I need to do for my helper and then in your layout file, you only need to declare that helper and specify the IDs of the widgets you want to apply to So, it makes basically — it’s a lot easier for you to package blocks of usable code and, you know, use them in your application So, going back to the code stuff. So, the other way we

thought about making your life easier, letting you build reasonable bricks is by moving to declarative way for animation. So, you can think about it as a specification for motion. And, we interpret this specification with a motion engine and on top of that, we are building a graphical motion editor. So, it’s something we introduced at Google I/O. We are still working on it. We decided to focus on the library side. Because kind of want to make sure it’s right for you and for your needs. But just a quick overview on the current build, it’s coming along and hopefully it will come soon, in a version of Studio So, that’s kind of like the overall approach we have for helping you. So, the helper on one hand and this motion specification on the other The thing that’s kind of nice, if I look at this, is that you can specify this motion and we’ll then take care of it. You don’t really have to write code for it So, the one we implemented is through MotionLayout. So, what is MotionLayout? It’s a view group. So, one caveat is that it means you can only animate the children of that view group and it’s a subclass. If you know ConstraintLayout, it’s great. You can directly use MotionLayout. On the flip side, you do have to use ConstraintLayout. But it does a lot. So, we do transitions, properties, we have a really good support for touch-driven motion. So it’s kind of like thinking values of animation and packaging it into a single place So, roughly-speaking, the only thing you have to understand is we are animating between two states. We have a start state and an end state and we interpret between those two things. So, in addition to basically supporting layout changes, essentially you have two virg versions of the layout, we support custom properties if you want to animate color and key frames and you can think about key frame as a modifier on that, you know, transformed between the start and the end So, to kind of summarize, with MotionLayouts, it tells you to think about your animation, your transition, your motion as a declaration. You just specify what it should do and we take care of it. It specifically is great when you want to do fine-tuned animation. So, it’s very specific what you want to do, it’s about coordinating together in a very specific way and finally, it’s really nice, as well, for the touch-driven motion motion I don’t think I need the mic So, I want to just kind of, like, show you guys a lot of things and be a little more visual from here on in. So, this is the way you want to create — carefully craft custom coordinated, crazy, cool animation. You can do stuff like that [Laughter] [Applause] So, how did we do that? It’s just two — two chains. The change into one chain and each letter’s a view and we use a stagger and a color change and a custom match view. It’s fairly simple to view. It took me a view minutes, it looks cool And that’s kind of what this stuff is all about So, the first thing, you can drive stuff out with touch. It will handle swipes. If you flick, it’ll go across quickly It understands velocity and manages that. The next thing to understand is we’re starting from two constraint sets but we have key frames and in this case, here, I’m starting with two constraint sets and I’m not having any key frames and you see how it crosses right there?

Right there, they overlap. So what you do is you add some key position, key frames, and you accelerate in the X — you finish the X part of the motion, halfway through and that gives you a kind of smooth, you know — you’ve seen this. It’s your settings menu [Laughter] So, the more extreme end of what we can do with key frames are key cycles and here, you can see a bunch of different kind of effects that we can do Essentially, anything that’s oscillating, it’s shaking, it’s bouncing around, you don’t want to actually go and build out complex paths with key frames This solves it. In alpha 2, we are introduing time cycles This is a crazy animation you can do with it. Of course, this is way too over-the-top and please don’t use this in product [Laughter] But — so, let’s get into how to use it Right. So — so, first of all, there’s information that we created so I’m going to go quickly. Please look at those articles. There is also a GitHub with examples One thing you may ask yourself is, okay, this is great. How do you use this in my application? There’s an example where you have a collapsible toolbar and to this kind of things with the normal collapsible toolbar, you can simply use a MotionLayout instead. You don’t really change anything else in your code, but collapsible becomes a MotionLayout and take all the advantages of it Similarly, you don’t have to use a new class, you can use MotionLayout for it. Same thing for view page. You can easily plug MotionLayout into it The last example is interesting It’s — it really looks — actually, this is pure MotionLayout. And what’s nice about it is that it actually is too MotionLayouts nested and we have one for collapsible to the bar, it’s the exact same one I used before. And it’s simply nested into a MotionLayout What’s really nice is that in order to specify this overall screen, I just need to create those two states, the start and end. You see that in the end, I simply make the MotionLayout that’s for the toolbar smaller and basically, we take care of all of it So, to summarize for the current state, we’re working on the graphical editor. But for the library, we did Google I/O and we did an alpha 2. And, you know, even in alpha, it’s built on 1.1 so it’s actually pretty stable. And in fact, because it’s pretty stable, quite a few people started to build stuff with it and we’ll go through some examples just to give you a little taste of what you can do with MotionLayout So, I looked on the Twitter a lot. I checked MotionLayout on Twitter all the time and I thought I would just share a few interesting animations that people have published. Most of these, you can actually find in GitHubs. These people publish them as videos and show them This guy’s been doing quite a few pieces of work with it It’s kind of interesting to see what he did here And this one is particularly interesting. Basically, you maybe notice in the previous one, there was a motion. Very nice. In this particular example, what’s nice is that it’s kind of like a view pager He added a way to drive it from code and that’s a very interesting, you know, future avenue for us. It’s a little bit — how can your code reuse some this previously-defined behavior? So, another one by him, the interesting thing here is it’s sort of mixing what is a normal RecyclerView and then sort of a reveal detail view. But it’s interesting MotionLayout It is super easy to come up with your own ways of doing these

kinds of transitions You’re not limited anymore This guy implemented a material design animation spec, but just using MotionLayout and a custom view that he built. It was a quite nice piece of work One of the things I liked about this one is it’s so original You see view pages. Okay. This is taking a whole new twist on it or spin on it, actually [Laughter] But you can see, it’s original You can sort of explore your own creativity or your team’s createty with what they like and what they do This one is interesting because it’s kind of like a typical coordinator layout stuff. You see it’s transparent and there’s special effects going on with things fading. It produces a unique, you know, custom view of the whole thing And this is our Chris Banes [Laughter] And, he did a very interesting one and it’s a whole app. All the codes involved is out there It is very custom. So, let’s take a closer look at it So, what’s great with it is this is the type of motion that is purely by code. There’s a lot of subtle coordination across so many elements. The text is fading, that poster is actually rotating, but actually matching. That’s what we mean when we are talking about motion or fine-tuned crafted motion This is the type of example that we hope we encourage you to build As a small sneak peek at what we’ll be having in alpha 3, it’ll support multiple states and allow you to interact with the multiple states purely from touch. So, this is one single MotionLayout, but in fact, it’s handling transitions between three transitions from a blank page to swiping the bottom to swiping a little bit, to swiping more. It’s all one page, one MotionLayout and it can produce a fairly sphistticated custom view This touch behavior, zero from your end. It’s all declarative [Applause and cheers] Pretty awesome. Cool. So, today, hopefully we’ve given you a guided tour from animated API and our goal was to make you more familiar with what they’re good at and what they’re not so good at so I’m going to try to summarize that as a takeaway The complex coordinated layout and for that nice hand-off between gesture and animation, really do check out MotionLayout If you need to build interruptable animations or gesture with the velocity tracking, look at the physics layout system If you need to do shared transitions, transitions is for you If you need to do vectors, do vector drawable If you need to do window animations, the original SDK 1 view animation system should be used If you need to animate properties of views, look at the view property animator If you need to do, like, custom view animation or driven by an amimation pulse, look at the animator Animator is your go-to default for general purpose animation Next time you have to build something, you won’t be paralyzed by choice of the different animation APIs. So, I thank you very much for joining us and we’ll be outside. Thanks very much [Applause] Hello? So, now it’s time for a completely different session that will last about two minutes long. We’re just closing out the day here. I was personally

curious whether you liked it or not. How many people liked the dev summit? [Applause] How many people didn’t like the dev summit and what are you doing here still, at the end of the second day? [Laughter] So maybe it worked. That would be cool. I think the people from my team and Google liked what happened. A community aspect hearing from you and being able to communicate the content. Hopefully we will hold this again. Hopefully it’ll be a little less than three years next time. We have to convince the people that write the checks there Some of the favorite things you saw this week? Just shout out? Don’t make it awkward MotionLayout all right. What else? Preferences. Nice. All right. Yeah, new little bit of thing coming out of the toolkit area. LiveData, yes. Very cool. Low latency audio. Yes and live-coding C++ in a five-minute lightning talk. App Bundles, yes. Kotlin native All right. Very interesting coming online What else? I heard paraside chat, which doesn’t — fireside, I heard of that one. Actually, that was really fun today. Did you like the chat? Good Awesome There is everything available, now, almost online already. Day one is already posted to YouTube. I heard earlier that day two is going to be live as early as 8:00 or 9:00 tonight Go back to your hotels or homes and watch it Also, you will be getting a survey, maybe it’s in your inbox right now. Please do fill out We do actually read this stuff and pay very close attention to it. Tell us what worked, tell us what didn’t and we will do those things for you because you are the reason that we’re doing this Let’s see. Anything else? I think that’s about it. I am looking forward to doing another one of these. Hopefully we’ll see you in 2021 In the meantime — [Laughter] In case you missed everything that happened, we tried to capture it in 90 seconds Welcome to the 2018 Android Dev Summit. This is an event for developers, by developers With over two billion devices, three-quarters of a trillion apps downloaded every year Android’s developer community is growing growing So, the Android App Bundle makes it much simpler. With no additional developer work needed, the App Bundle now makes apps an average of 8% smaller to download for devices We simply could not do this without you, so thank you [Applause and cheers] As Dave just said, thank you Thanks for coming