Flex企业应用开发实践学习笔记(五)-------组件失效机制

本文介绍了Flex中的组件失效机制,该机制通过延迟方法调用来提高应用程序性能。文章详细解释了如何通过不同失效方法通知组件更新,并探讨了Flex如何通过callLater方法实现这一机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     组件失效机制(invalidation mechanism)是Flex用来提高应用性能的一项技术,组件生命周期与布局主要利用这一机制来实现,本节对该机制进行总结并探讨该机制如何实现。

     1. 什么是组件失效机制

     在组件的生命周期中,应用可能会改变组件的大小和位置,改变组件的属性来控制组件的显示,或者更改组件的样式和皮肤属性。比如,可能更改组件中所显示文本(Text )的字体(font)。组件中文本字体发生变化,那么组件的尺寸也可能随之变化,这就会影响到组件的布局。从前面的内容中我们可以知道,布局操作会使Flex自动调用自定义组件的commitProperties()、measure(), layoutChrome()以及updateDisplayList()等一系列方法。

     通过程序来更改“字体(font)”这个属性值的执行速度远远快于Flex渲染图形和更新屏幕的速度。因此,应该在确定最终字体之后再更新布局。

当设置了组件的多个属性后,每个属性都可能影响到组件的尺寸,比如Button控件的label和icon属性,开发者肯定希望所有属性全部设置完成后一次性地执行commitProperties()、measure()和updateDisplayList()方法,而不是在设置完label属性后执行一遍这些方法,然后在设置icon属性后又执行一遍这些方法。

     另外,可能会有多个组件同时改变字体,组件的字体改变都可能会引起组件尺寸的变化,从而影响它们之间的相对位置。这时应该让Flex去协调布局操作,以消除冗余处理,而不是每个组件更新字体之后都执行一次布局操作。

Flex使用失效机制来同步组件的变更。正如前面所讲到的那样,Flex用一系列方法的调用来标记组件的某些东西已经发生变化,然后将其延迟到下一次屏幕更新时通过布局管理器统一调用组件的commitProperties()、measure()、layoutChrome()以及updateDisplayList()方法。

表2-1列出了组件中有关“失效(invalidation)”的方法。

表2-1   组件中“失效”方法列表

失效方法

描述

invalidateProperties()通知组件,以使下次屏幕更新时,它的commitProperties()方法能被调用
invalidateSize()通知组件,以使下次屏幕更新时,它的measure()方法能被调用
invalidateDisplayList()通知组件,以使下次屏幕更新时,它的layoutChrome()方法和updateDisplayList()方法能被调用

     当组件调用失效方法时,它通知Flex,该组件已经被更新,需要重新渲染和布局。当多个组件调用失效方法时,Flex会协调这些更新,以使这些更新操作在下一次屏幕更新时一起执行。通常,组件使用者不必直接调用这些失效方法。这些失效方法被组件的setter方法或组件的其他方法根据需要进行调用。


2. Flex如何实现“失效机制”

 

Flex通过UIComponent的callLater()方法实现组件的“失效机制”。callLater()方法声明如下:

  1. public function callLater(method:Function, args:Array = null):void

callLater是一个非常重要的底层方法,callLater方法将给定的method及其参数args放入内部队列中,当下一次屏幕更新时调用内部队列中的方法。那么“下一次屏幕更新”指的是什么呢?通过研究callLater方法的源代码我们发现callLater方法主要做三件事情:

      1) 首先将需要延迟调用的method方法及其参数args放入组件的内部队列中。

      2) 为舞台(Stage)对象的ENTER_FRAME和RENDER事件设置侦听器,在这两个事件的侦听器中会调用在“内部队列”中延迟的方法。队列中的方法一旦被调用就会从队列中清除。

      3) 调用舞台(stage)对象的invalidate()方法,这样Flash Player在显示列表渲染前能够派发RENDER事件。

因此,回顾图1-5所示的“Flash Player执行帧中ActionScript代码及渲染图形过程”,我们可以得出以下结论:如果在“用户动作”阶段的代码中调用callLater方法,则callLater方法中method参数所指定的方法将在“失效动作”阶段被调用。如果在“失效动作”阶段的代码中调用callLater方法,则callLater方法中的method参数所指定的方法将在下一帧ENTER_FRAME事件派发时调用。

代码清单2-22通过callLater方法实现了文字移动效果。调试状态下执行这段代码,查看控制台中的输出结果可以验证以上结论。

代码清单2-22   通过callLater方法实现文字移动效果


  1. <?xml version="1.0"?> 
  2. <!-- CallLater.mxml --> 
  3. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
  4.       enterFrame="this.onEnterFrame(event)"> 
  5.     <mx:Script><![CDATA[  
  6.     [Bindable]  
  7.     public var text:String = "这是一串通过callLater方法实现滚动文字";  
  8.     [Bindable]  
  9.     //文字移动速度。  
  10.     public var speed:Number = 5;  
  11.     import flash.display.Stage  
  12.     public function initTicker():void  
  13.     {  
  14.         //从右侧开始移动文字  
  15.         theText.move( this.width+10, 0 );  
  16.         callLater(moveText);  
  17.     }  
  18.     private function onEnterFrame(event:Event):void  
  19.     {  
  20.       trace("----------------进入新一帧------------------------");  
  21.     }  
  22.     public function moveText():void  
  23.     {  
  24.         var xpos:Number = theText.x;  
  25.         if( xpos-speed+theText.width < 0 )  
  26.         {  
  27.             xpos = this.width+10; //从右侧开始移动文字  
  28.         }  
  29.         xpos -= speed;  
  30.  //每帧应当执行两次该代码,分别在进入帧和渲染显示列表前各执行一次。  
  31.         trace(speed, xpos);  
  32.  //该代码的调用将导致显示列表失效,从而RENDER事件被Flash派发。  
  33.         theText.move(xpos,0);  
  34. // 如果下面代码在"失效动作"阶段执行,则moveText方法将 在进入新一帧时被调用。如果该代码在进入新一帧时被调用,也 就是在"用户动作"阶段被调用,则moveText方法将在"失效动作"阶 段执行,也就是在渲染显示列表前执行。  
  35.         callLater(moveText);  
  36.     }  
  37.       public function changeSpeed():void  
  38.     {  
  39.         speed = speedSelector.value;  
  40.     }  
  41.     ]]> 
  42. </mx:Script> 
  43.     <mx:Panel title="步进器例子" width="400" height="200"> 
  44.         <mx:Canvas creationComplete="initTicker()" 
  45.                 horizontalScrollPolicy="off"  backgroundColor="red" color="white"   width="100%"> 
  46.             <mx:Label id="theText" text="{text}" y="0"/> 
  47.         </mx:Canvas> 
  48.         <mx:HBox> 
  49.             <mx:Label text="速度:"/> 
  50.             <mx:HSlider minimum="1" maximum="10" value="{speed}" 
  51.                 id="speedSelector" snapInterval="1" tickInterval="1" 
  52. change="changeSpeed()"/> 
  53.         </mx:HBox> 
  54.     </mx:Panel> 
  55. </mx:Application> 

通过调试我们可以发现,在执行一帧的过程中,moveText()方法被执行两次,因为trace(speed, xpos)方法输出了两次。调试状态下,控制台输入如下所示:

  1. ----------------进入新一帧------------------------  
  2. 5 1025  
  3. ----------------进入新一帧------------------------  
  4. 5 1020  
  5. 5 1015  
  6. ----进入新一帧------------------------------------  
  7. 5 1010  
  8. 5 1005  
  9. ----------------进入新一帧------------------------  
  10. ......
//代码中的speed 绑定可能会有点问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值