We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Layout traversals on Android

00:00

Formal Metadata

Title
Layout traversals on Android
Title of Series
Number of Parts
46
Author
License
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
Understanding how a UI framework behaves under the hood is key if you want to push the boundaries of the platform and write solid UI code. Layout traversals are at the heart of Android’s UI toolkit. What happens behind the scenes in requestLayout() call? What kind of layout optimizations Android implements? In this talk, we’ll go through some of the key steps that the Android UI framework takes to display your UI on the screen, from a layout perspective.
18
Lecture/Conference
Block (periodic table)Touch typingCrash (computing)BuildingFundamental theorem of algebraSoftware frameworkLecture/Conference
RepetitionSoftware frameworkBitTouch typingTrajectoryLecture/Conference
Computing platformTrajectoryPattern languageAndroid (robot)Lecture/Conference
Surjective functionTendonInternet forumOpen setOpen sourceShared memorySinc functionProjective planeWindowExterior algebraProgram flowchart
Sinc functionProjective planeTerm (mathematics)Game theoryExterior algebraBasis <Mathematik>Computing platformCross-platformLecture/ConferenceComputer animation
Theory of relativityRevision control
RepetitionComputing platformMobile WebSoftware developerOpen sourceProcess (computing)Lecture/Conference
Keyboard shortcutHacker (term)Web 2.0
Wallpaper groupAndroid (robot)Data storage devicePattern languageMobile appMultiplication signSoftware developerGodFacebook
Menu (computing)FacebookPhase transitionAndroid (robot)Fundamental theorem of algebraDemosceneMultiplication signSoftware frameworkOpen sourceComputing platformSystem callXMLUMLLecture/ConferenceMeeting/Interview
System callFundamental theorem of algebraCodeComputing platformAndroid (robot)Lecture/Conference
Perspective (visual)Computing platformAndroid (robot)MathematicsComputer architectureLecture/ConferenceMeeting/Interview
Keyboard shortcutInteractive televisionComputer architecturePosition operatorTouchscreen1 (number)Key (cryptography)Touch typingFrame problemEvent horizonElement (mathematics)State of matterXMLUMLLecture/Conference
CuboidTerm (mathematics)Android (robot)CurveLecture/ConferenceMeeting/Interview
Computer architectureCurveBit rateSoftware development kitTerm (mathematics)Projective planeDisk read-and-write headJSON
Drop (liquid)Android (robot)ConsistencySpacetimeLecture/Conference
Multiplication signPredictabilityoutputTerm (mathematics)Computer architectureConsistencyCodeLecture/ConferenceMeeting/Interview
Range (statistics)Bit rateCodeMeeting/Interview
TouchscreenContent (media)Directed graphBit rateState of matterFrame problemMeeting/Interview
Computer architectureFrame problemMultiplication signTerm (mathematics)Block (periodic table)BuildingFundamental theorem of algebraDiagram
OvalBuildingBlock (periodic table)Fundamental theorem of algebraFrame problemEvent horizonMultiplication signJava appletCodeTerm (mathematics)outputState of matterSystem callOrder (biology)Lecture/ConferenceMeeting/Interview
Validity (statistics)View (database)HierarchyTraverse (surveying)Connectivity (graph theory)Core dumpReverse engineeringCASE <Informatik>MathematicsAndroid (robot)RootImpulse responseRoutingLecture/ConferenceJSONXMLUML
RepetitionRoutingPhysical systemHierarchyState of matterView (database)Computing platformTouch typingMobile appRootSurfaceEvent horizonLecture/Conference
Android (robot)View (database)RootPerspective (visual)Impulse responseRoutingPosition operatorFigurate numberOperator (mathematics)Lecture/Conference
View (database)MeasurementRepetitionEvent horizonOperator (mathematics)VolumenvisualisierungSoftware frameworkView (database)Traverse (surveying)MeasurementRecursionNetwork topologyComputer animationLecture/Conference
MeasurementCache (computing)MeasurementNetwork topologyOperator (mathematics)Reverse engineeringCycle (graph theory)WeightTheory of relativityMultiplicationMessage passingTraverse (surveying)Lecture/Conference
Interior (topology)OvalMeasurementFlagMeasurementTerm (mathematics)Traverse (surveying)Reverse engineeringView (database)Focus (optics)Multiplication signPosition operatorJSONLecture/Conference
Frame problemOvalTerm (mathematics)Position operatorSoftware frameworkLaptopPattern languageXMLComputer animation
Electronic visual displayElectronic mailing listDynamic random-access memoryMoving averageArithmetic meanComputer hardwareElectronic visual displayElectronic mailing listAndroid (robot)Lecture/Conference
Electronic visual displayInvariant (mathematics)MeasurementMultiplication signSoftware frameworkValidity (statistics)Electronic mailing listElectronic visual displayLine (geometry)BitLecture/ConferenceMeeting/Interview
Clique-widthView (database)WaveHookingMeasurementPosition operatorInvariant (mathematics)CodeMeeting/Interview
MeasurementState observerTouchscreenObject (grammar)Frame problemResource allocationNetwork topologyProper mapXMLUML
Right angleNetwork topologyHierarchyRepresentation (politics)RootCuboidMultiplication signImpulse responseLecture/ConferenceDiagram
Inheritance (object-oriented programming)OvalMultiplication signCodeInheritance (object-oriented programming)Term (mathematics)Traverse (surveying)HierarchyFrame problemRootJava appletView (database)Impulse responseVideoconferencingRoutingJSON
Electronic visual displayComputer hardwareMultiplication signComplex (psychology)Electronic mailing listReverse engineeringFlagFrame problemView (database)Term (mathematics)RootSystem callCodeTraverse (surveying)SpacetimeLecture/Conference
Set (mathematics)Inheritance (object-oriented programming)OvalBoolean algebraElectronic mailing listElectronic visual displayRootNetwork topologyValidity (statistics)JSONDiagram
System callObject (grammar)Frame problemInformationoutputLecture/Conference
OvalGroup actionOrder (biology)Software frameworkoutputInvariant (mathematics)Traverse (surveying)Network topologyState observerLecture/ConferenceJSONXMLUML
Exterior algebraBitSlide ruleLecture/Conference
State of matterBoolean algebraBlogGroup actionSlide ruleSoftware frameworkPattern languageView (database)Frame problemPoint (geometry)Power (physics)Different (Kate Ryan album)Translation (relic)State of matterLecture/Conference
Boolean algebraPower (physics)Software frameworkImplementationNetwork topologyDialect2 (number)Group actionTraverse (surveying)MathematicsFrame problemReverse engineeringLecture/Conference
Context awarenessDialectView (database)Software frameworkElectronic visual displayElectronic mailing listMereologyNetwork topologyHierarchyOperator (mathematics)Level (video gaming)WeightTheory of relativityLecture/ConferenceMeeting/Interview
View (database)WeightCausalityMeasurementNetwork topologyElectronic mailing listLevel (video gaming)Theory of relativityImplementationHierarchyMultiplicationXMLUML
Drop (liquid)View (database)BitBlogSoftware frameworkWritingLecture/Conference
Software frameworkView (database)Keyboard shortcutProjective planeFacebookLecture/Conference
Lecture/Conference
Transcript: English(auto-generated)
Good morning first of all Let me do something It's becoming kind of a tradition Can you say hi three two one?
Oh, it's I'm filming myself. Haha. Sorry, okay Okay, here we go, okay now cool Thank you Hopefully this thing will not crash and I'll have to record again Yeah, it did crash. Okay. Never mind. Okay. Thanks for coming
I really like to talk about this because It touches like some of the very fundamental building blocks of the framework and as a UI engineer I think if you're doing any UI work I think it's really important to have a very good understanding of like how the the basic things of the framework works
so before I start Just like yeah, I'm Lucas. I'm Brazilian and I've been in Europe for About eight years and I've been doing you why for a bit longer than that actually about like ten years
so I'll start by Telling a bit about my trajectory as a UI engineer because that touches a bit of the the main topics that I want to cover today because a lot of the The trajectory of Android as a platform or more specifically as a UI platform
Follows a very common pattern on UI toolkits in general So in many ways this talk will cover the specifics of Android but a lot of these techniques and a lot of the way layout works and on Android is applicable to
Pretty much any toolkit you can think of now any modern toolkit anyway so Do you know what this is? Yeah, has anyone used this is anyone like you're like old enough Cool one. Okay, so this is know 1.4
That's the first thing I worked on as an open source contributor back in the day 2001 or something and This is like very like back Then we were trying to attack the windows market share and try to provide an open Alternative like and I've been like in the gnome project since kind of the early days
until this gnome 2 which was much cooler actually and one cool thing about like in terms of the UI took it story here is GTK the kind of the do I took it that is the basis for everything you do on gnome? Was created as an alternative to motive has anyone used motive here
Cool like Okay, so and GTK was something that arose from the game project the graphical tool like if you're using Linux you probably know about this and I think it's cross-platform, but mostly used on Linux and
GTK was evolving as the desktop Platform evolved with it so GTK 2 was much more advanced than GTK 1 in many ways was mostly an API cleanup, but it's still like was pretty a big step forward in relation to the the version 1
then I started doing more GTK stuff and Nokia and That was in the very beginnings of like the more modern devices that we know today has anyone does anyone know what this is Okay cool So this is a my ammo based Device it was like this Linux based platform that Nokia was trying to do
to push for like back in 2006 or so so that was my first like experience with like mobile development and but it was still very desktop like in many ways and This was this was really fun This is like golden ages of Nokia doing a lot of a lot of open-source Linux people got hired
So it was like a dream job for someone who working on on Linux back back then Then I started working on something called The web book it's this thing so it was basically still again a bunch of like gnome hackers who got together to
Basically develop a new OS and this was my first experience with like a very motion driven kind of UI and And for those who track like gnome stuff like little was the creator of like the JS bindings for that is Like what runs gnome 3 nowadays, so that was the first
Gjs thing back back then so it's pretty fun then I got into Android development and That's when like started doing Android stuff Full-time so I I assume you maybe you've heard of like this little app called pattern is a little wallpaper app
They got like got featured quite a few times in the App Store and and then Firefox for Android And now Facebook which is mysterious because I can't disclose what I'm working on yet, but hopefully soon cool, so
Throughout all these phases One thing that I realized and going like through like different like API's and platforms and frameworks like the thing that is Like became very clear to me is like if you assume that you know how the toolkit works You'll probably be shooting yourself in the foot like all the time because yeah
You're probably assuming wrong things most of the time And we're lucky that like Android is an open source platform, and we can see how things work And I think this is extremely valuable as a new engineer because you can track how what actually is happening behind the scenes when you do fundamental things like request layout calls and so and such so
A biggest the biggest reason why I do this talk is I think we need to be more deliberate about our UI code To get the most out of the platform And that's what I'll be covering today
So in many ways this is a talk about the basics of Android But instead of talking about the API from a user perspective a user of the platform perspective I'll be doing something from inside out, so I'll be taking the basics and talking about how it works from under the hood
So the architecture of UI took it's pretty much any UI took it you can think of like From desktop to mobile. I think the the biggest change that happened like in the last 10 years with UI took it's is that motion became a very central piece of like the architecture and
The interactions moved from mouse and keyboard to touch But other than that the architecture is pretty much the same You have all you always have something of a layout Notion that defines size and position of everything you have a notion of rendering you paint things on screen And you have a notion of like
Interacting with these elements and changing their state through touch or key events and such so The old school and that's my framing by the way. There's nothing. This is nothing academic It's just the way I framed the history of UI took its in general When you talk about the old-school stuff the GTK ones and twos
and the motives and Tcl TKs like the very old-school stuff it was basically this notion that you nest boxes in boxes and You pretty much focus a lot on layout and the rudimentary in with a very rudimentary notion of motion
so if you look at the how these like UI took it's got implemented. They were all Assuming a static layout for the most part and if there was a motion is kind of like a bonus And it was super hacky and clunky
so and Funny enough like Android is actually kind of like behind the curve in terms of what is considered a modern It was behind the curve When it comes to like modern toolkit architecture to jelly bean so project butter Which sounded like a really cool like bleeding edge kind of thing was something that like many took its head for years
so the notion that like Like the whole notion of like synchronizing everything with refresh rate was like not new at all So jelly bean was kind of like Android catching up with like what is considered a modern UI took it in many ways
So if you look at like how jelly bean or pre jelly bean Android was Implemented you had this notion of like it was basically a handler with a looper And you would just post stuff whenever you want to relay out the UI And this is why you get like you got a lot of like inconsistent behavior with animations and the animations AP the animation API's until Hanukkah were very rudimentary, so
Android caught up like I think it's pretty much a modern toolkit nowadays But it took longer than like most of the players in the in the same space so if you think about like a what is a modern UI took it is Is the way I define is to a UI took it that has a very predict
Predictable notion of time and pace so everything that happens in terms of input layout and motion and especially motion because One of the main drivers of like the new architecture is that you can do motion and it's consistent and Reliable and it always behaves the same way unless you're doing something really wrong with your UI code
but modern toolkits have a tick and The way this tech is defined is usually from the refresh rate of the device So the thing that we talk if you look at like the most of the devices in the market today They they basically have like a range they range from like 58 to 60
Megahertz like of refresh rate and that is Where the 60 frames per second comes from? the frames of having 16 ish Milliseconds comes from the refresh rate of the target devices that we're working with nowadays so and
Modern toolkits like use that as a reference and there's a reason for that one you want you don't want to do more than You need so you don't want to do refresh more than the The device can do because you'll be wasting Battery and a bunch of like resources on the device and you don't want to do you go you refresh this content of UI
halfway the tearing problems If you have like half of your screen in one state and the other half in other and another So the sink has this is basically what orchestrates all the updates in the UI So in Android terms the architecture the over architecture is like driven by something called choreographer
That was introduced in Jelly Bean and the the notion that the the overall notion that of frames is a very cool Aspect of the of this architecture so you have frames and every time you need to change something every time that you interact with The UI you cue an update in the next frame And that's a very important thing to frame any questions any any work you're doing in the UI
It's pretty much about queuing stuff in the next frame That's the fundamental building block of everything we do on Android nowadays more than Android So if you look at the choreographer dot Java code You'll have something like he hooks into the in the v-sync
events and every time a new frame is called from v-sync like it will check if there's any pending work and there's one important aspect here in terms of the order of these calls because this is a very Important aspect in terms of framing questions about UI to you always handle input first
Because that will probably invalidate and request layout in your state then your handle animations will which again will probably call triggering validations in your view hierarchy And then you do the traversal which will probably mean in practice redrawing or in in case of layout changes a layout reversal
So Another core component of Android is View root impulse which is is not a public API But it's the thing that sits at the top of your view hierarchy So your your root view or the root view of the activities is not actually
the root of your view hierarchy if your root evil is the thing that sits on the top of everything and it will it understands how to update like the UI from top down and bottom-up in a minute in some ways especially for for touch event handling and That's the piece of the platform that interacts with the surface flinger to compose the new state
Of your app with the state of the system UI like which means status bar navigation bar and so forth and the notion of of Views in in in Android is driven mostly
from This root view root impulse so again like so from from a user perspective What we have is These three steps I think like I will assume that everyone is is aware of these three steps that each view has to go through
So you always measure which means figure out the size of things layout commit the size to a certain position and draw which means collecting operations to render these thing once once the the vsync event happens So let's have a look at like how this is done, and I'll try to go through this
Step by step and like highlighting some aspects of the framework which I consider interesting for for today, so You measure and that's when you call like measure and I'll measure In a view and this is a recursive operation like traversal is a recursive operation throughout the whole tree
And then there's something called lazy measure like which I'll just briefly mentioned today but it's this notion that like you cache the pair of like measure specs and You make sure that like you don't remeasure things when you don't need to so
before KitKat When you had multi-pass layouts like things with layout weights and relative layouts and stuff like that you would cache the last Measurement from the view, but if you go if you went through measurement again in the same cycle You would miss the cache and call a lot of measurements in the in the same layout reversal so lazy measure basically
caches the all the pairs of measure specs using the same traversal and Whenever layout is called it will check if measure is has been postponed to the layout and you call all measure only once so
This is actually I Predict that Google will be doing a lot of work in terms of like optimizing layout traversals on the measurement measurements back aspect Mostly around text for example like text is very expensive to measure and you don't want to measure things all the time and
Multi-pass layouts at the top of like a top-level views is it can be very expensive, too So this is probably going to be a focus in terms of performance the next step is layout which is positioning things at at their position and in the framework terms layout and on layout and that's pretty much when you commit laptop
right button to your to reviews That's the simple one and then draw which calls again follows the same pattern draw and on draw which and the hardware celebrated world means Updating display lists like is everyone familiar with the notion of this playlist like who's not familiar with this playlists
Okay, cool. So this playlist like that. It's It's something that is not obvious like from just looking at the API But like the notion of draw on Android is not that you're actually executing drawing commands
synchronously on your draw calls like what Android does actually is When you implement a unknown draw method with the canvas API What canvas is essentially doing is collecting or your or your commands and storing that in the list? So every time you invalidate something you're basically
Recreating the list of commands and then these commands will be pushed to To the GPU later at like a convenient time for the framework so So whenever you invalidate something What you're essentially doing is asking the the framework to recreate the display list. I'll talk a bit about that in a minute so
But the bottom line here, that's pretty much the takeaway. I want from this is understanding invariance of the UI took it and Invariants are layout when you run layout you definitely measured everything already
And if you're drawing something you definitely have positions and sizes committed to all the views already So if you have that in mind you won't hand wave When like oh, why is the width of this thing not defined you probably didn't measure yet? And if you're doing this in an arbitrary piece of the code that doesn't assume that like that doesn't like
Hook into the the UI took it in the right place you'll be in a bad situation So a few code smells for UI took it if you're doing get measure with get measure height outside layout You're probably doing something wrong
so If you want to do it in the proper way, you're probably hooking into the the Tree observer callbacks and waiting for layout and doing things more deliberately Allocations and same way if you're doing allocations on layout that's probably
Okay, ish because layout is not called many times during traversal if you're doing allocations in on measure You should probably try to avoid it as much as possible and I'll draw like just don't like never Allocate anything on on draw because on draw is called in each frame in an animation for example So we'll be allocating a lot of objects so like that's kind of like a very general
guideline for allocations, so Think that's more interesting when you change things, so I just described okay. You have something on screen, so what happens When you want to change things so the first notion is that we're probably familiar with this like notion of request layout, right?
so What does request layout actually do? is to bubble up your layout request up to the root the root impulse like the purple box there and what and
one important aspect here that I want to highlight is This is one of the reasons why having deep trees view hierarchy trees is expensive because you have to go all the way up Every time you call it, so this is a very visual representation of why this could be expensive So in terms of like layout view dot Java code
If you look at request layout it will just check the parent did I request layout yet? Yes If not Then I do a request layout on a parent and that bubbles up into like the root of the your view hierarchy And in terms of like your root impulse whenever this request layout reaches the top of your view hierarchy
It will cue a traversal to the in the next frame So and that means that if you call request layout like a hundred times in the same frame You will not do a hundred layout traversals You just do one in the next frame, but you will do bubbling up things up to the root in each goal
So you should avoid? Calling it too often Invalidation is when you want to redraw something and as I mentioned in the display list space world this means recreate my display list and In complex views and this is why the recommendation is to usually use hardware layers for
For complex views is because you want to avoid recreating display lists in each frame So in terms of like code invalidation adds a flag to validate the view and then when the draw call Is triggered in the next frame? you be basically checking that and recreating the display list and
one important thing here is invalidation Is not something that invalidates the path up to the root It just invalidates the thing that you call invalidate on so it's not like request layout that invalidates the path in the tree up to the root
Okay, so and last but not least when you're doing animations The post on animation and your object animators what they're essentially doing is Cuing a callback in the next frame, so just as a reminder. It's this thing here So it's the callback animation and like another piece of like information
That is very important when you're framing your UI questions is so if I'm running an animation I know that I handled input already So if you have something that deals with animations and input the order is guaranteed This is an invariant of the framework so you can rely on the fact that input is handled whenever you're running or you put your
Callbacks, but you're not you haven't run the traversal yet I briefly mentioned tree observer because I think it's a if you're an API that's not used as often as I would expect and if you want to be deliberate about
When to call things when the size is defined on pre draw listener is probably the right way to do it It's a bit more verbose than like Alternatives, but like that's the deliberate like the deliberate kind of API that you should be using when you want to check for Guarantee that the size of things is defined
And one interesting piece. I wrote a bit about that like I'll post the slides later But like the this blog post explains how the transitions framework works, and it's heavily Reliant on this API so the way the transitions framework that got introduced and turns in KitKat
Relies on something that follows this pattern and this is a pattern that you can use yourself without the transitions framework by the way Where you save the state of your views which means translation sizes and and so forth Then you wait for the next frame to be laid out
And you're about to draw and then you restore the state and animate a difference That's essentially how the transitions framework works and that in on the same token how the activity transitions work and all that This is a very simple pattern that you can use if you want to do
Funky layout transitions by hand and I'm not suggesting that you should do it, but again the idea my my point here is Understand the basics so you have the power to deviate from what the framework offers whenever you need it And you should be confident about that so basic tips
Never do layout and layout like this is bad like this is the worst ever so if you're doing something on in the newer Layout implementation, and you call request layout there What will happen is that at the end of the full traversal of the tree it will check did anyone request layout? Yes, then I'll do the traversal all over again in the same frame, so you're probably skipping frames if you're doing this in animations
The second is no layouts no layout traversals in animation so never change size or anything like that Manually the transitions framework has private api's to do size transitions Efficiently, but with public api's you can do that so you don't want to traverse the whole tree in each frame
This will probably not do 63 frames per second at all so let's not do that And invalidate regions if you can if you're instead of validating the whole view Try to figure out what part of the view got invalidated
So you're giving enough context to the framework to figure out like what views needs to be redrawn and the display list that need to be recreated and From understanding the basics. I think it becomes a lot more obvious like why simplifying view hierarchy is is a good thing because
You avoid a lot of like traversing the tree back and forth if you have a deep tree This would be more expensive so simplifying view tree is about making this basic operations more efficient and Avoid multi-pass layout like layout weight and relative layout especially at the high level like top level of your tree Because this will cause multi measurement in the whole in the whole ui basically if you have that like there at like
The like down in leave on the leaves of your tree That's probably less expensive because you're just dealing with a couple of views in there so list views and stuff that's not like hugely expensive and
If you want to know more about custom views a good way to simplify a view hierarchy is to implement custom like layouts and I know it sounds kind of scary at first But if you understand the basics again And if you know a couple of like apis you can do a lot by basically hard coding your layout
Because you know what you want instead of using these general-purpose things that can be very expensive So I wrote a bit about that like if you if you want to know more about like the different techniques you can use to write the custom layouts and custom views have a look at this blog post and And flattening things is great, but like you have to be careful, so if you're doing a lot of custom drawing
That means you're not relying on the view framework anymore So make sure that like if you go flat you're accounting for the drawbacks of that so just to give you an example if you're drawing text Manually with like a canvas api you lose
Accessibility you lose keyboard navigation you lose all these things so if you're doing like custom stuff Make sure that you're like doing this deliberately and accounting for the the kind of compromises you have to make cool We're doing some really deep stuff with layout at Facebook in a couple of projects in London, so if
you are interested in this kind of like crazy stuff that should be a pretty fun place to be and That's what I have for you today. Thank you