This document discusses layout and animation performance in Android. It begins with an overview of how motion is perceived by the human eye and how to achieve smooth motion. It then covers topics like measuring and laying out views, optimizing for the GPU, using hardware layers for animation, and getting size information during animation using ViewTreeObserver. The document provides guidance on profiling performance, reducing unnecessary layout requests, and techniques for creating smooth animations in Android.
13. How Is Motion Perceived?
Smooth
Motion
60
No
Difference
60+
Flip Book
12
Movies
Frames Per Second
Fluid Motion
24
+effects
14. We Have A Winner!
Smooth
Motion
60
No
Difference
60+
Flip Book
12
Movies
Frames Per Second
Fluid Motion
24
+effects
Smooth
Motion
60
Colt McAnlis: https://youtu.be/CaMTIgxCSqU
35. GPU Profiling
● A graph per visible app
● A bar per frame
● Render time corresponds height
● 16 millis benchmark (green)
● Crossing = skipping frame
https://developer.android.com/studio/profile/dev-options-rendering.html
39. Vsync / Misc Time
Misc = (vsync timestamp) - (timestamp when received)
→ work on the UI thread between two consecutive frames
● Choreographer log : “Missed vsync by XX ms skipping XX frames”
High? move work off UI Thread
VSync/
Misc
Input
Animation
Measure/
Layout
Draw
Sync &
Upload
Command
Issue
Swap
Buffers
41. Animation
Evaluate all running animators
Often : object animator, view property animator, and transitions
High?(2milis+) check custom animators / unintended work
VSync/
Misc
Input
Animation
Measure/
Layout
Draw
Sync &
Upload
Command
Issue
Swap
Buffers
42. Measure / Layout
Executing layout and measure callbacks for needed view.
More on that in a few slides :)
VSync/
Misc
Input
Animation
Measure/
Layout
Draw
Sync &
Upload
Command
Issue
Swap
Buffers
44. Sync & Upload
Upload bitmap to the GPU.
High?
Too many images
Too big of an image
VSync/
Misc
Input
Animation
Measure/
Layout
Draw
Sync &
Upload
Command
Issue
Swap
Buffers
46. Swap Buffers
CPU done rendering and wait for GPU ack.
High?
A lot of GPU work
VSync/
Misc
Input
Animation
Measure/
Layout
Draw
Sync &
Upload
Command
Issue
Swap
Buffers
52. Step 1: Measure
Goal: obtain view size,
including its descendants size
REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)
53. Step 1: Measure
Goal: obtain view size,
including its descendants size,
agreed by its parent.
REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)
54. Step 1: Measure - What’s View SIZE?
- width & height (aka: drawing width & drawing height) -
- Actual size on screen, at drawing time and after layout.
REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)
55. Step 1: Measure - What’s View SIZE?
- width & height (aka: drawing width and drawing height)
- the actual size of the view on screen, at drawing time and after layout.
- measured width & measured height
- how big a view wants to be within its parent
REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)
58. ViewGroup.LayoutParams
How big the View wants to be
For each dimension, it can specify one of:
an exact number
MATCH_PARENT
WRAP_CONTENT
*Might be subclassed, like in RelativeLayout
60. Multiple measure() Calls
measure() may be called more than once
For example:
- Call once with UNSPECIFIED
- If size too big/small- evaluate
- Call with exact size
61. Step 1: Measure - How Does It Work?
● measure(int, int)
○ → (calls onMeasure() which should be overridden)
● Set measuredWidth & measuredHeight
○ (can call super)
● Including for the View's descendants.
● respects parents’ constraints.
REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)
62. Step 1: Measure - Reminder
Goal: obtain view size,
including its descendants size,
agreed by its parent.
REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)
65. Step 2: Layout
Goal : set position for view and all its children
REF: http://developer.android.com/reference/android/view/View.html#onLayout(boolean, int, int, int, int)
66. Step 2: Layout
● layout(int, int, int, int)
○ → (calls onLayout() which should be overridden)
● Assign a size and position to a view and all of its descendants
○ (can call super)
● Including for the View object's descendants.
● respects parents’ constraints.
REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)
67. - View draws itself with size and position from previous steps.
- onDraw(Canvas) is called
- Canvas object generates (or Updates) a list of OpenGL-ES
commands (displayList) to send to the GPU.
Step 3: Draw (AKA Update)
REF: http://developer.android.com/reference/android/view/View.html#onDraw(android.graphics.Canvas)
Guide: http://developer.android.com/training/custom-views/custom-drawing.html
69. When Things Change...
E.g. text, color, size, padding, margin...
A view notifies the system, by calling:
Invalidate - which will call the onDraw again, or
requestLayout - which will call the entire process again.
75. So it seems that layout passes once...
Or is it?
76. Root View : RelativeLayout
2 passes per change:
1)By views’ requests
a)Then relativeLayout calculates by relations & weights
2)Determine the final positions for rendering.
78. Root View : LinearLayout
Generally issues 1 layout request
Unless:
●measureWithLargestChild(true)
○ Children with weights will have minimum size of largest child
●Nested weights
79. Root View : GridLayout
Allows relative positioning,
while preprocessing the child view relationships.
82. It Usually Works Fine… But...
●Root elements
●Deep view hierarchy
●Too many (i.e. list)
Can hurt.
83. What can we do?
●Flatten hierarchy :
Removing unneeded views
Merge on include
flatter layout
Beware double layout taxation
Minimize layout requests
95. Constraint Layout
●Api 9+
●Performance oriented:
○ Reduce nesting
○ Improve measure/layout
○ Best practice : top level, without nesting layouts
User friendly:
Expressive
96. The New Layout Editor
Android Studio 2.2 Preview
Designed for ConstraintLayout - but not only!
Works with all layouts
Better with custom views (use View.isInEditMode())
More features : like editing menu resources….
97. Setting Up
1.Android Studio 2.2 Preview
2.Android Support Repository (version 32+):
3.Add the library on your build.gradle file:
dependencies {
compile 'com.android.support.constraint:constraint-layout:1.0.0-
alpha3'
}
101. Idea
View has 4 sides : left, top, right, bottom + baseline for textview
So we can:
Connect view side to layout
Connect 2 view sides
Align 2 view sides
Align 2 textview baselines
102. Side Constraint Handle
Locate the view within the layout.
app:layout_constraintRight_toRightOf="@+id/text_like_count"
103. Baseline Constraint Handle
align the baseline of multiple textviews
app:layout_constraintBaseline_toBaselineOf="@+id/text_title"
115. Deleting Constraints
Single constraints -
click the anchor point
All constraints for a view
button when view is selected
All constraints for layout
icon on top bar
118. Well, that about it!
Not officially released, but quite stable.
Give it a try :)
https://codelabs.developers.google.com/codelabs/constraint-layout/index.html
122. Animation
Reminder : Changing a view property causes invalidation.
Same for animation, when changing the animated property
(e.g. x coordinate, scale, alpha value etc.)
124. View Layer - Hardware Acceleration
Render into an off-screen buffer (backed by Hardware)
Texture is created in the GPU for our view
Change properties without invalidating
Smoother animation
https://developer.android.com/guide/topics/graphics/hardware-accel.html#drawing-support
125. View Layer - Hardware Acceleration
ScreenGPU
Polygons
Textures
CPU
new
Button()
DisplayList
Make Changes Here
126. Properties
alpha: Changes the layer's opacity
x, y, translationX, translationY: Changes the layer's position
scaleX, scaleY: Changes the layer's size
rotation, rotationX, rotationY: Changes the layer's orientation in 3D space
pivotX, pivotY: Changes the layer's transformations origin
134. What if we want the
size during an animation?
135. ViewTreeObserver
●Provided by the view hierarchy
●Use to register listeners to view tree global changes
○ For example: layout of the whole tree, beginning of the drawing, touch mode
change....
●Use with getViewTreeObserver()
https://developer.android.com/reference/android/view/ViewTreeObserver.html
137. Tips During Animation
Don’t request measure / layout
Before / After / Tree Observer
Don’t inflate
explicitly or implicitly by launching an activity
Animate properties that do not trigger layout
For example: translationX and translationY and not LayoutParams properties
144. Tips
1.measure() only during layout()
2.No layout() during layout()
3.No layout / measure during animation
4.No inflation during animation
5.Minimize requestLayout()
6.Invalidate regions when possible [rather than whole view]
145. Tips
7. New allocations during traversal :
On layout - ok-ish
On measure - avoid
On draw - no way! [called each frame!]
146. Tips
8. Animate without trigger layout
9. Animate with hardware acceleration
Clean up
Don’t invalidate on layer