This document provides an overview of the Flex component lifecycle presented by RJ Owen. It discusses the main phases of the lifecycle: birth (construction, configuration, attachment, initialization), life (invalidation, validation, interaction), and death (detachment, garbage collection). Key methods in the lifecycle are explained such as constructors, createChildren(), commitProperties(), measure(), and updateDisplayList(). The importance of deferment and avoiding direct updates to the display list is emphasized.
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Adobe Flex 3 Component Life Cycle
1. Adobe Flex 3 Component
Lifecycle
Presented by RJ Owen
This presentation originally created by
RJ Owen and Brad Umbaugh in 11/08.
2. Who are we?
‣ RJ Owen
Senior Technical Architect @ EffectiveUI
•
• Adobe Community Expert in Flex
3. Who are you (hopefully)?
‣ Beginner to intermediate level developers
‣ Anyone who doesn’t currently understand
the lifecycle
‣ Anyone who wants a good review of the
basics
5. Flex
‣ What is Flex?
A set of components
•
• MXML
• The component lifecycle!
6. Flex Component Lifecycle
‣ What is it?
The way the framework interacts with
•
every Flex component
• A set of methods the framework calls to
instantiate, control, and destroy
components
• Methods that make the most of the
elastic racetrack
7. Elastic Racetrack: introduction
image courtesy of Ted Patrick
‣ Flex component lifecycle is built on this
frame model
‣ More on this later
8. A frame in AS3
image courtesy of Sean Christmann
9. Phases of the Lifecycle
‣ 3 Main Phases:
‣ BIRTH:
construction, con guration,
•
attachment, initialization
‣ LIFE:
• invalidation, validation, interaction
‣ DEATH:
• detachment, garbage collection
11. Construction
Birth
construction
con guration
attachment
initialization
Life
Death
12. What is a constructor?
‣ A function called to instantiate (create in
memory) a new instance of a class
Birth
construction
con guration
attachment
initialization
Life
Death
13. How is a constructor invoked?
Actionscript:
var theLabel : Label = new Label();
MXML:
<mx:Label id=quot;theLabelquot;/>
Birth
construction
con guration
attachment
initialization
Life
Death
14. What does a constructor have access to?
‣ Properties on the class
‣ Methods on the class
‣ Children have not yet been created!
Birth
construction
con guration
attachment
initialization
Life
Death
15. What does an ActionScript3
constructor look like?
public function ComponentName()
{
super();
//blah blah blah
}
‣ No required arguments (if it will be used in
MXML); zero, or all optional
‣ Only one per class (no overloading!)
‣ No return type
‣ Must be public
Birth
construction
con guration ‣ Calls super() to invoke superclass constructor; if
attachment
you don’t, the compiler will!
initialization
Life
Death
16. What does an MXML constructor
look like?
‣ No need to de ne one. In fact, if you try
to put one in an <mx:Script> block, you’ll
get an error.
‣ Why? Remember: MXML = Actionscript. A
constructor is created by the compiler in
the Actionscript generated from the
MXML.
‣ Specify “-keep” in the Flex Builder
Birth
compiler arguments and look at the
construction
con guration
generated code to verify this.
attachment
initialization
Life
Death
17. What should a constructor do?
‣ Not much.
Since the component’s
children have not yet been created, there’s
not much that can be done.
‣ There are speci c methods (such as
createChildren) that should be used for
most of the things you’d be tempted to
put in a constructor.
‣ A good place to add event listeners to the
Birth
object.
construction
con guration
attachment
initialization
Life
Death
18. Don’t create or attach children in
the constructor
‣ It’s best to delay the cost of createChildren
calls for added children until it’s necessary
Birth
construction
con guration
attachment
initialization
Life
Death
19. Con guration
Birth
construction
con guration
attachment
initialization
Life
Death
20. Con guration
‣ The process of assigning values to
properties on objects
‣ In MXML, properties are assigned in this
phase, before components are attached or
initialized
<local:SampleChild property1=quot;value!quot;/>
Birth
construction
con guration
attachment
initialization
Life
Death
21. Hooray: Sample code!
<mx:Application ...>
...
<local:SampleChild property1=quot;value!quot;/>
</mx:Application>
Output:
SampleChild constructor
SampleChild.property1 setter
Birth
Adding child SampleChild4
construction
con guration
attachment
initialization
Life
Death
22. Con guration and Containers
‣ Containers must not expect their children
have to be instantiated when properties
are set.
<mx:Application ...>
<local:SampleContainer property1=quot;value!quot;>
<local:SampleChild property1=quot;value!quot;/>
</local:SampleContainer>
</mx:Application>
SampleContainer constructor
Birth
SampleContainer.property1 setter
construction
SampleChild constructor
con guration
attachment SampleChild.property1 setter
initialization
Life
Death
23. Con guration Optimization
‣ To avoid performance bottlenecks, make
your setters fast and defer any real work
until validation
‣ We’ll talk more about deferment in the
validation / invalidation section
Birth
construction
con guration
attachment
initialization
Life
Death
24. Attachment
Birth
construction
con guration
attachment
initialization
Life
Death
25. What is attachment?
‣ Adding a component to the display list
(addChild, addChildAt, MXML declaration)
‣ The component lifecycle is stalled after
con guration until attachment occurs.
Birth
construction
con guration
attachment
initialization
Life
Death
26. Consider this component:
public class A extends UIComponent
(It traces all of its methods.)
{
public function A() {
trace( quot;CONSTRUCTORquot; );
super();
}
override protected function createChildren() : void {
trace( quot;CREATECHILDRENquot; );
super.createChildren();
}
override protected function measure() : void {
trace( quot;MEASUREquot; );
super.measure();
}
override protected function updateDisplayList(width:Number, height:Number) : void {
trace( quot;UPDATEDISPLAYLISTquot; );
super.updateDisplayList(width,height);
}
override protected function commitProperties():void {
trace( quot;COMMITPROPERTIESquot; );
super.commitProperties();
}
27. And this application:
<mx:Application ...>
<mx:Script>
<![CDATA[
override protected function createChildren() : void {
super.createChildren();
var a : A = new A();
}
]]>
</mx:Script>
</mx:Application>
Output: CONSTRUCTOR
‣ Without attachment, the rest of the lifecycle
doesn’t happen.
28. But what about this application?
<mx:Application ...>
<mx:Script>
<![CDATA[
override protected function createChildren() : void {
super.createChildren();
var a : A = new A();
this.addChild( a );
}
]]>
</mx:Script>
Output: CONSTRUCTOR
</mx:Application>
CREATECHILDREN
COMMITPROPERTIES
MEASURE
UPDATEDISPLAYLIST
‣ Moral of the story: don’t add components to the
stage until you need them.
29. Initialization
Birth
construction
con guration
attachment
initialization
Life
Death
30. Initialization
‣ 2 phases, 3 events:
1. ‘preInitialize’ dispatched
Create 2. createChildren(); called
3. ‘initialize’ dispatched
Validate 4. rst validation pass occurs
5. ‘creationComplete’ dispatched
Birth
construction
con guration
attachment
initialization
Life
Death
31. createChildren()
‣ MXML uses the createChildren() method to add
children to containers
‣ Override this method to add children using AS
Follow MXML’s creation strategy: create,
•
con gure, attach
override protected function createChildren():void
{
...
create textField = new UITextField();
textField.enabled = enabled;
con gure textField.ignorePadding = true;
textField.addEventListener(quot;textFieldStyleChangequot;,
textField_textFieldStyleChangeHandler);
...
...
attach addChild(DisplayObject(textField));
}
32. createChildren() cont.
‣ Defer creating dynamic and data-driven
components until commitProperties()
‣ UIComponent.createChildren() is empty,
but it’s good practice to always call
super.createChildren() anyway
Birth
construction
con guration
attachment
initialization
Life
Death
33. rst validation pass
‣ Invalidation is not part of initialization -
only Validation
‣ Validation consists of 3 methods:
• commitProperties()
• measure()
• updateDisplayList()
‣ more on these later
Birth
construction
con guration
attachment
initialization
Life
Death
36. Invalidation / Validation cycle
‣ Flex imposes deferred validation on the
Flash API
• goal: defer screen updates until all
properties have been set
‣ 3 main method pairs to be aware of:
• invalidateProperties() ->
commitProperties()
• invalidateSize() -> measure()
• invalidateDisplayList() ->
updateDisplayList()
38. Deferment
‣ Deferment is the central concept to
understand in the component Life-cycle
‣ Use private variables and boolean ags to
defer setting any render-related
properties until the proper validation
method
39. Text-book example
Bad:
public function set text(value:String):void
{
myLabel.text = value;
// Possible Error! during first config phase,
// myLabel might not exist!
}
Good:
private var _text:String = quot;quot;;
override protected function
public function set text(value:String):void
{ commitProperties():void{
{
textSet = true;
_text = value; if(textChanged){
myLabel.text = _text;
textChanged = true;
textChanged = false;
}
invalidateProperties();
invalidateSize(); super.commitProperties();
}
invalidateDisplayList();
}
40. The Elastic Racetrack revisited
image courtesy of Sean Christmann
Invalidation occurs here
41. Invalidation methods
‣ invalidateProperties()
Any property changes
•
‣ invalidateSize()
• Changes to width or height
‣ invalidateDisplayList()
• Changes to child component size or
position
Birth
Life
invalidation
validation
interaction
Death
42. Invalidation example 1
<mx:Application>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var arr : ArrayCollection = new ArrayCollection();
public function onClick() : void {
var c : int = 0;
while( c++ < 20 ) {
arr.addItem( c );
}
}
]]>
</mx:Script>
<mx:VBox>
<mx:Button label=quot;Click me!quot; click=quot;onClick()quot;/>
<test:BadList id=quot;theListquot; dataProvider=quot;{arr}quot;/>
</mx:VBox>
</mx:Application>
43. Invalidation example 2
public class BadList extends VBox
{
private var _dataProvider : ArrayCollection;
public function set dataProvider( arr : ArrayCollection ) : void {
this._dataProvider = arr;
arr.addEventListener( CollectionEvent.COLLECTION_CHANGE,
dataProviderChangeHandler );
}
private function dataProviderChangeHandler( e : Event ) : void {
this.removeAllChildren();
for each( var n : Number in this._dataProvider ) {
var l : Label = new Label();
l.text = n.toString();
this.addChild( l );
}
}
public function BadList() {}
}
Result: dataProviderChangeHandler called 20 times
44. Invalidation example 3
public class GoodList extends VBox
{
private var _dataProvider : ArrayCollection;
private var _dataProviderChanged : Boolean = false;
public function set dataProvider( arr : ArrayCollection ) : void {
this._dataProvider = arr;
arr.addEventListener( CollectionEvent.COLLECTION_CHANGE,
dataProviderChangeHandler );
this._dataProviderChanged = true;
this.invalidateProperties();
}
override protected function commitProperties():void {
super.commitProperties();
if( this._dataProviderChanged ) {
this.removeAllChildren();
for each( var n : Number in this._dataProvider ) {
var l : Label = new Label();
l.text = n.toString(); Result: commitProperties
this.addChild( l );
called only twice (once
}
during initialization)
this._dataProviderChanged = false;
}
}
private function dataProviderChangeHandler( e : Event ) : void {
this._dataProviderChanged = true;
this.invalidateProperties();
}
public function GoodList() {}
}
47. Validation
‣ Apply the changes deferred during
invalidation
‣ Update all visual aspects of the
application in preparation for the render
phase
‣ 3 methods:
• commitProperties()
• measure()
Birth
• updateDisplayList()
Life
invalidation
validation
interaction
Death
48. commitProperties()
‣ Ely says: “Calculate and commit the effects
of changes to properties and underlying
data.”
‣ Invoked rst - immediately before
measurement and layout
Birth
Life
invalidation
validation
interaction
Death
49. commitProperties() cont.
‣ ALL changes based on property and data
events go here
‣ Even creating and destroying children, so
long as they’re based on changes to
properties or underlying data
‣ Example: any list based component with
empty renderers on the screen
Birth
Life
invalidation
validation
interaction
Death
50. measure()
‣ Component calculates its preferred
(“default”) and minimum proportions
based on content, layout rules,
constraints.
‣ Measure is called bottom up - lowest
children rst
‣ Caused by “invalidateSize()”
‣ NEVER called for explicitly sized
Birth
components
Life
invalidation
validation
interaction
Death
51. overriding measure()
‣ Used for dynamic layout containers (VBox,
etc.)
‣ Use getExplicitOrMeasuredWidth() (or
height) to get child proportions
‣ ALWAYS called during initialization
‣ Call super.measure() rst!
‣ Set measuredHeight, measuredWidth for
the default values; measuredMinHeight
Birth
and measuredMinWidth for the minimum.
Life
invalidation
validation
interaction
Death
52. measure() cont.
‣ Not reliable - Framework optimizes away
any calls to measure it deems
“unecessary”
‣ Ely says: “Start by explicitly sizing your
component and implement this later.”
Birth
Life
invalidation
validation
interaction
Death
53. updateDisplayList()
‣ All drawing and layout code goes here,
making this the core method for all
container objects
‣ Caused by invalidateDisplayList();
‣ Concerned with repositioning and
resizing children
‣ updateDisplayList() is called top-down
Birth
Life
invalidation
validation
interaction
Death
54. Overriding updateDisplayList()
‣ Usually call super.updateDisplayList() rst
• super() is optional - don’t call it if you’re
overriding everything it does
‣ Size and lay out children using move(x,y)
and setActualSize(w,h) if possible
• I never have good luck with
setActualSize()
Birth
Life
invalidation
validation
interaction
Death
55. Elastic Racetrack cont.
‣ User Actions
Dispatch invalidation events
•
• Interact with any non-validation events
from this frame (mouse movements,
timers, etc.)
56. Elastic Racetrack Cont.
‣ Invalidate Action
Process all validation calls
•
‣ Render Action
• Do the heavy lifting - actually draw on
the screen
59. How do objects know when
something happens?
‣ Events: objects passed around when
anything interesting goes on (clicks,
moves, changes, timers...)
‣ If something happens to a component, it
“ res” or “dispatches” the event
‣ If another component wants to know
when something happens, it “listens” for
events
Birth
‣ Event-based architecture is loosely-
Life
invalidation
coupled
validation
interaction
Death
60. Bene ts of Loosely-Coupled
Architectures
‣ Everything becomes more reusable
‣ Components don’t have to know anything
about the components in which they’re
used
Birth
Life
invalidation
validation
interaction
Death
61. Who can dispatch events?
‣ Subclasses of EventDispatcher
EventDispatcher inherits directly from
•
Object
‣ Simply call dispatchEvent(event) to re off
an event when something happens
Birth
Life
invalidation
validation
interaction
Death
62. How to tell events apart?
‣ Event class
Different classes allow for customized
•
payloads
‣ “type” eld: a constant
Birth
Life
invalidation
validation
interaction
Death
63. Common Events
‣ Event.CHANGE
‣ MouseEvent.CLICK
‣ FlexEvent.CREATION_COMPLETE
‣ Event.RESIZE
‣ MouseEvent.ROLL_OUT
Birth
Life
invalidation
validation
interaction
Death
64. Handling Events
‣ <mx:Button id=”theButton”
click=”callThisFunction(event)”/>
‣ theButton.addEventListener( MouseEvent
.CLICK, callThisFunction )
Birth
Life
invalidation
validation
interaction
Death
65. Event Propagation
‣ Three phases: Capturing, Targeting, Bubbling
Application Application
Capturing Bubbling
Phase Phase
Target
Targeting
Phase
Birth
Life
invalidation
validation
interaction
Death
67. Event Propagation
----------------------------------------------------------
TARGET: button
CURRENT TARGET: eventTest
PHASE: CAPTURE
----------------------------------------------------------
TARGET: button
CURRENT TARGET: outer
PHASE: CAPTURE
----------------------------------------------------------
TARGET: button
CURRENT TARGET: inner
PHASE: CAPTURE
----------------------------------------------------------
TARGET: button
CURRENT TARGET: button
PHASE: TARGET
----------------------------------------------------------
TARGET: button
CURRENT TARGET: inner
PHASE: BUBBLE
----------------------------------------------------------
TARGET: button
CURRENT TARGET: outer
PHASE: BUBBLE
----------------------------------------------------------
Birth TARGET: button
CURRENT TARGET: eventTest
Life
PHASE: BUBBLE
invalidation
validation
interaction
Death
68. Stopping events from propagating
‣ stopPropagation() : Prevents processing
of any event listeners in nodes
subsequent to the current node in the
event ow
‣ stopImmediatePropagation() : Prevents
processing of any event listeners in the
current node and any subsequent nodes
in the event ow
Birth
Life
invalidation
validation
interaction
Death
69. target vs. currentTarget
‣ target: the object that dispatched the
event (doesn’t change)
‣ currentTarget: the object who is currently
being checked for speci c event listeners
(changes)
Birth
Life
invalidation
validation
interaction
Death
70. Dispatching events from custom
components
‣ MXML:
<mx:Metadata>
[Event(name=quot;atePizzaquot;, type=quot;flash.events.BradEventquot;)]
</mx:Metadata>
‣ Actionscript:
[Event(name=quot;atePizzaquot;, type=quot;flash.events.BradEventquot;)]
public class MyComponent extends UIComponent
{
...
}
Birth
Life
invalidation
validation
interaction
Death
71. gutterShark: event manager
‣ guttershark is Aaron Smith’s “Actionscript
3 Productivity Library”
‣ Contains a lot of stuff commonly needed
when developing Flash web sites
‣ Includes an EventManager that’s helpful
Birth
Life
invalidation
validation
interaction
Death
72. gutterShark: event manager
<mx:Application
initialize=quot;onInitialize()quot;>
<mx:Script>
<![CDATA[
import net.guttershark.events.EventManager;
private var em : EventManager;
public function onInitialize( e : Event = null ) : void {
em = EventManager.gi();
em.handleEvents(theButton,this,quot;onButtonquot;);
}
public function onButtonClick() : void {
theLabel.text = quot;CLICKquot;;
}
public function onButtonMouseOver() : void {
theLabel.text = quot;MOUSE OVERquot;;
}
public function onButtonMouseOut() : void {
theLabel.text = quot;MOUSE OUTquot;;
}
]]>
Birth </mx:Script>
<mx:VBox>
Life
<mx:Button id=quot;theButtonquot; label=quot;Click Me!quot;/>
invalidation <mx:Label id=quot;theLabelquot;/>
</mx:VBox>
validation
</mx:Application>
interaction
Death
73. gutterShark: event manager
‣ Supports many different types of events
and the addition of more
‣ Easy integration with Google Analytics,
Atlas, Webtrends
‣ http://www.guttershark.net
Birth
Life
invalidation
validation
interaction
Death
76. Detachment
‣ “Detachment” refers to the process of
removing a child from the display list
‣ These children can be re-parented
(brought back to life) or abandoned to die
‣ Abandoned components don’t get
validation calls and aren’t drawn
‣ If an abandoned component has no more
active references, it *should* be garbage-
Birth
collected
Life
Death
detachment
garbage
collection
77. Detachment cont.
‣ Re-parenting isn’t cheap, but it’s cheaper
than re-creating the same component
twice
‣ Children do not need to be removed from
their parent before being re-parented, but
always should be
‣ Consider hiding rather than removing
• set visible and includeInLayout to false
Birth
Life
Death
detachment
garbage
collection
79. Garbage Collection
‣ The process by which memory is returned
to the system
‣ Only objects with no remaining references
to them will be gc’d
• Set references to detached children to
“null” to mark them for GC
‣ Consider using weak references on event
listeners
‣ Talk to Grant Skinner about forcing GC
Birth
Life
http://gskinner.com/blog/archives/2006/08/as3_resource_ma_2.html
•
Death
detachment
garbage
collection
80. Conclusion
‣ Defer, Defer, DEFER!
‣ Use validation methods correctly
‣ Remember the elastic racetrack
‣ Always look on the bright side of
detachment.
81. References
‣ Ely Green eld: “Building a Flex Component”
• http://www.on ex.org/ACDS/
BuildingAFlexComponent.pdf
‣ Cha c Kazoun, Joey Lott: “Programming Flex 2” by
O’Reilly
• http://oreilly.com/catalog/9780596526894/
‣ Colin Moock: “Essential Actionscript 3.0” by O’Reilly
• http://oreilly.com/catalog/9780596526948/
index.html