Flex组件生命周期(整理版)

1、生命周期(LifeCycle)简述
⑴调用组件构造函数。构造函数没有返回类型,没有参数,使用super()调用父类的构造器
⑵使用set,get设置组件属性,常在set方法内监控一个布尔变量来实现失效机制
⑶调用addChild()方法将组件添加到父组件显示列表中,FLEX将自动调用createChildren(),invalidateProperties(),invalidateSize(),invalidateDisplayList()。只有将组件添加到父容器中,FLEX才能确定它的大小(size),设置它所继承样式(style)属性,或者在屏幕上画出它
⑷组件的parent 属性设置为对父容器的引用
⑸样式(style)设置
⑹组件分发preinitialize事件
⑺调用组件createChildren()方法
⑻调用 invalidateProperties(),invalidateSize(),invalidateDisplayList()失效方法,FLEX将在下一个“渲染事件”(render event)期间对相应的commitProperties(),measure(), updateDisplayList()方法进行调用。这个规则唯一例外就是当用户设置组件的height 和width 属性时, Flex 不会调用measure()方法。也就是说,只有当组件的explicitWidth 和explicitHeight 属性是NaN 时Flex才会调用measure()方法。
⑼组件分发initialize事件。此时组件所有的子组件初始化完成,但组件尚未更改size和布局,可以利用这个事件在组件布局之前执行一些附加的处理
⑽在父容器上分发childAdd事件
⑾在父容器上分发initialize事件
⑿在下一个“渲染事件”(render event)中, Flex 执行以下动作:
a.调用组件的commitProperties()方法
b.调用组件的measure()方法
c.调用组件的layoutChrome()方法
d.调用组件的updateDisplayList()方法
e.在组件上分发updateComplete事件
⒀如果commitProperties(), measure(),updateDisplayList()方法调用了invalidateProperties(),invalidateSize(),invalidateDisplayList()方法,则Flexh 会分发另外一个render事件
⒁在最后的render事件发生后, Flex执行以下动作:
a.设置组件visible属性使其可视
b.组件分发creationComplete事件,组件的大小(size)和布局被确定,这个事件只在组件创建时分发一次
c.组件分发updateComplete事件。无论什么时候,只要组件的布局(layout),位置,大小或其它可视的属性发生变化就会分发这事件,然后更新组件来正确地显示。
2、为什么使用失效机制(invalidation mechanism)
一种情况是,当设置了组件的多个属性后,比如Button 控件的label 和icon 属性,我们需要所有属性被设置后一次性执行commitProperties(), measure(), updateDisplayList()方法,而不是设置过label 属性后执行一遍这些方法,然后在设置icon属性后又执行一次这些方法。
另一种情况是几个组件同时更改了它们的字体大小。程序更改字体大小的执行速度大大快于Flex 更新应用的速度,因此要在确定最终更改字体之后才开始更新布局。另外,Flex 需要协调布局操作以消除任何冗余过程,而不是在每个组件更新它的字体大小之后都执行一次布局操作。
Flex 使用“失效机制(invalidation mechanism)”来同步组件的更改。Flex 用一系列方法的调用,比如在setter方法内监控一个变更变量来标记组件的某些东西已经发生变化, 然后在下一个“渲染事件(renderevent)”中触发组件的commitProperties(), measure(), layoutChrome(),updateDisplayList()检查这些布尔变量来完成最终的变更逻辑。这样做的额外好处就是setter方法可以更迅速地返回,把对新属性值的处理留给了commitProperties()方法。
失效方法及其对应的触发函数如下:
invalidateProperties() 通知组件,以使下次屏幕更新时,它的commitProperties()方法被调用。
invalidateSize() 通知组件,以使下次屏幕更新时,它的measure()方法被调用。
invalidateDisplayList() 通知组件,以使下次屏幕更新时它的layoutChrome()方法和
updateDisplayList()方法能被调用。
当组件调用一个“失效”方法时,它就通知Flex该组件已经被更新。当多个组件调用失效
方法,Flex 会在schedules中协调这些更新,以使这些更新操作在下一次屏幕更新时一起执行。注意,createChildren()没有对应的失效方法,它会在调用后被立即执行。



1. Initlization


Construction
Construction是组件构造阶段,组件的构造器不能有必须的参数 。在构造函数中可以添加事件 监听器,初始化属性。这个阶段只做很少的事情。

Configuration
Configuration是组件的配置阶段,组件的属性,事件回调函数,样式和效果 定义都在这个阶段完成。你不应该把这些任务推迟到Attachment和Initlization阶段之后。

Attachment
Attachment阶段是把该组件追加到显示列表当中,一个Flex组件会被一个Flex容器IContianer以addChild方法添加到显示列表当中。

Initlization
在Initlization初始化阶段,组件会执行一次完整的invalidation/validation周期。这个阶段做的工作流程是:

    * 发出preinitialize事件。
    * 执行方法createChildren()
    * 发出initialize事件。
    * 行一次完整的invalidation/validation周期。
    * 发出creationComplete事件。





2. Updating


用户可能会与组件产生交互,组件的位置大小可能改变,样式可能被重新赋值,也可能获得焦点或者被禁用等等。这些情况的发生都用影响到组件外观的变化。所以组件需要重绘自身来响应这些变化。

Invalidation
如果一个组件的属性改变,它可能就会标记组件为失效状态。

Validation
一个组件被标记失效后,会验证是否需要更新组件,如果需要会调用 相关的方法来更新。组件有三个极其重要的方法来更新自己:

    * commitProperties()
    * measure()
    * updateDisplayList(unscaledWidth,unscaledHeight)

除了这三个方法,还有一个重要的方法是styleChanged(styleName),当某个样式改变时,styleChanged被调用,然后执行Invalidation标记组件。如果你有自定义一个组件,有一些法则必要得遵守:

不要在子类中显式调用commitProperties,measure和updateDisplayList这三个方法,你要做的是override,而不是call。如果你添加了新的样式,同样是要继承styleChanged方法,加入自己的逻辑。



3. Destruction


Detachment
当不需要这个组件时,把它从显示列表中移出。把组件从一个容器中移出再添加到另一个容器中比创建新的组件有更小的开销。

Garbage Collection
如果组件不再被引用时,它就成为符合垃圾回收的对象 了,所以垃圾回收的第一条准则是不再有活动的引用。
更加值得注意的是第二条准则,即不包含使用了强引用的事件监听器,Dictionary和Timer。
所以尽量使用弱引用是多么重要,但是同样,小心你的弱引用在不该回收的时刻被回收了。例如对函数中的临时变量使用弱引用,你可能得不到你想要的异步结果



next stone -->

Flex组件在初始化阶段会依次触发下列的几个事件 :

preinitialize  -  当组件在创建的原始阶段触发,它的子元素都还没有创建
initialize  -  当组件及其子元素都已经创建完毕的时候触发,但此时组件的大小尺寸还没有决定
creationComplete  -  当组件布局完成并显示之后触发

因此,我们一般在initialize的时候,可以对组件上要显示的字符信息等进行设置;尤其是在该时刻设置和组件尺寸相关的值。而要获取和组件布局相关的信息的操作,则放在creationComplete时。



Flex组件的实例化生命周期

我们来看下面这段MXML代码
< ? xml version="1.0" ?>
< mx:Application  xmlns:mx ="http://www.adobe.com/2006/mxml" >
     < mx:Box  id ="box1"  width ="200" >
         < mx:Button  id ="button1"  label ="Submit" />
     </ mx:Box >
< / mx:Application >


和这段MXML等同的ActionScript代码是:
var  box1:Box  =   new  Box();
box1.width = 200 ;

var  button1:Button  =   new  Button()
button1.label  =   " Submit " ;

box1.addChild(button1);


其实,当你用MXML创建组件时,Flex SDK会生成相应的AS代码,以上代码在看似简单,但在执行过程中会发生很或的事情,我们来看下创建Button组件时执行的流程:
1)调用构造方法来创建实例
var button1:Button = new Button();

2)对创建的Button实例设置属性
button1.label = "Submit";

3)调用Button实例的addChild()方法把按钮添加到父容器中
box1.addChild(button1);

在调用这行代码的时候,将会产生以下动作:
a.设置组件实例的parent属性,使其关联到父容器
b.设置组件实例的样式
c.触发组件实例的add事件
d.触发父容器的childAdd事件
e.触发组件实例的preinitialize事件,触发时,组件实例处于非常原始的状态
f.创建组件实例的子元素
g.组件触发initialize事件,此时,组件和其子元素都已经创建完毕,但和布局相关的属性都还没有处理

4)显示应用,render事件被触发,并且会做以下处理:
a.所有涉及显示和布局相关的东西被处理完成
b.设置组件的visible属性为true
c.组件的creationComplete事件被触发
d.组件的updateComplete事件被触发

-----------------------官方文档-------------------------------------

原文 来自Adobe live doc

The component instantiation life cycle describes the sequence of steps that occur when you create a component object from a component class. As part of that life cycle, Flex automatically calls component methods, dispatches events, and makes the component visible.

The following example creates a  Button   control in ActionScript and adds it to a container:

// Create a Box container.
var boxContainer:Box = new Box();
// Configure the Box container.

// Create a Button control.
var b:Button = new Button()
// Configure the button control.
b.label = "Submit";
...
// Add the Button control to the Box container.
boxContainer.addChild(b);

The following steps show what occurs when you execute the code to create the Button control, and add the control to the Box container:

   1. You call the component's constructor, as the following code shows:

      // Create a Button control.
      var b:Button = new Button()

   2. You configure the component by setting its properties, as the following code shows:

      // Configure the button control.
      b.label = "Submit";

      Component setter methods might call the  invalidateProperties() ,  invalidateSize() , or  invalidateDisplayList()   methods.
   3. You call the  addChild()   method to add the component to its parent, as the following code shows:

      // Add the Button control to the Box container.
      boxContainer.addChild(b);

      Flex performs the following actions:
         1. Sets the  parent   property for the component to reference its parent container.
         2. Computes the style settings for the component.
         3. Dispatches the  preinitialize   event on the component.
         4. Calls the component's  createChildren()   method.
         5. Calls the  invalidateProperties() ,  invalidateSize() , and  invalidateDisplayList()   methods to trigger later calls to the  commitProperties() ,  measure() , or  updateDisplayList()   methods during the next  render   event.

            The only exception to this rule is that Flex does not call the  measure()   method when the user sets the height and width of the component.
         6. Dispatches the  initialize   event on the component. At this time, all of the component's children are initialized, but the component was not sized or processed for layout. You can use this event to perform additional processing of the component before it is laid out.
         7. Dispatches the  childAdd   event on the parent container.
         8. Dispatches the  initialize   event on the parent container.
   4. During the next  render   event, Flex performs the following actions:
         1. Calls the component's  commitProperties()   method.
         2. Calls the component's  measure()   method.
         3. Calls the component's  layoutChrome()   method.
         4. Calls the component's  updateDisplayList()   method.
         5. Dispatches the  updateComplete   event on the component.
   5. Flex dispatches additional  render   events if the  commitProperties() ,  measure() , or  updateDisplayList()   methods call the  invalidateProperties() ,  invalidateSize() , or  invalidateDisplayList()   methods.
   6. After the last  render   event occurs, Flex performs the following actions:
         1. Makes the component visible by setting the  visible   property to  true .
         2. Dispatches the  creationComplete   event on the component. The component is sized and processed for layout. This event is only dispatched once when the component is created.
         3. Dispatches the  updateComplete   event on the component. Flex dispatches additional  updateComplete   events whenever the layout, position, size, or other visual characteristic of the component changes and the component is updated for display.

Most of the work for configuring a component occurs when you add the component to a container by using the  addChild()   method. That is because until you add the component to a container, Flex cannot determine its size, set inheriting style properties, or draw it on the screen.

You can also define your application in MXML, as the following example shows:

< mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Box>
        <mx:Button label="Submit"/>
    </mx:Box>
< /mx:Application>

The sequence of steps that Flex executes when creating a component in MXML are equivalent to the steps described for ActionScript.

You can remove a component from a container by using the  removeChild()   method. If there are no references to the component, it is eventually deleted from memory by the garbage collection mechanism of Macromedia Flash Player 9 from Adobe.

------------------------------------翻译-------------------------------------

关于组件实例化生命周期
描述执行的序列步骤,当你从一个组件类创建一个组件时。作为生命周期的一部分,Flex自动调用组件方法,分发事件,使组件可视。
下例是在AS中创建一个按钮并增加到一个容器中:
1.调用组件的构造函数,新建一个组件:
// Create a Button control.
var b:Button = new Button()

2.通过设置它的属性,配置组件,如:
// Configure the button control.
b.label = "Submit";

3.你调用addChild()方法来增加组件到它的父对象:
// Add the Button control to the Box container.
boxContainer.addChild(b);

Flex执行如下的动作:
a.为组件设置parent属性引用它的父容器
b.计算组件的style设置
c.在组件上分发preinitialize事件
d.调用组件的createChildren()方法
e.调用invalidateProperties(),invalidateSize(),和invalidateDisplayList()方法,以触发延迟的调用commitProperties(),measure(),或updateDisplayList()方法在下一个render事件期。
这条规则仅有的例外是Flex不调用measure()方法当用户设置组件的height和width时。
f.在组件上分发initialize事件。在这时,组件的所有子对象被初始化,但这个组件组件还未为布局而被尺寸化或处理,你能使用这个事件来执行这个组件附加的处理,在它被布局前。
g.分发childAdd事件在父容器上
h.分发initialize事件在父容器上

4.在下一个render事件期间,Flex执行如下的行为:
a.调用组件的commitProperties()方法
b.调用组件的measure()方法
c.调用组件的layoutChrome()方法
d.调用组件的updateDisplayList()方法
e.在组件上分发updateComplete事件

5.Flex 分发附加render事件,如果commitProperties(),measure(),或updateDisplayList()方法调用 invalidateProperties(),invalidateSize(),或invalidateDisplayList()方法。

6.在最后的render事件执行后,Flex执行如下动作:
通过设置visible属性为ture让组件可视
分发creationComplete事件在组件上。组件为布局被sized和processed。这个事件仅被分发一次当组件被创建时。
分发updateComplete事件在组件上。Flex分发附加的updateComplete事件不管何时布局,位置,尺寸,或组件别的可视特性改变,并且组件被更新显示。

为配置一个组件的多数的工作执行,当你使用addChild()方法,增加一个组件到一个容器。这是因为,直到你增加组件到一个容器,Flex不能决定它的尺寸,设置继承的style属性,或画它在屏幕上。
在MXML里增加一个组件的步骤等效于AS中执行的步骤:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml ">
    <mx:Box>
        <mx:Button label="Submit"/>
    </mx:Box>
< /mx:Application>
从一个容器中删除一个组件,通过使用removeChild()方法,如果没有引用到这个组件,它最终会被内存中删除,由Flash Player9的垃圾回收机制。

你可能感兴趣的:(Flex,application,button,actionscript,methods,construction)