1

我有一个小问题。

环境

环境:Flex 3(实际上更新到 Flex 4 SDK,但仍然使用mx而不是spark

IDE:Flash Builder 4.6。

浏览器:火狐14.0.1

Flash 播放器版本:FP 11 调试器 - 11.2.202.235

状态语法:Flex 3 风格的语法。

应用程序

我有一个应用程序。

此应用程序有几个状态。

其中一个状态依次具有wrapperComponent具有三种不同状态的“”:基本状态(即“”)、“ firstState”和“ secondState”。

稍微简化一下,几乎每个状态都包含一个不同的自定义组件,如下所示:

  • wrapperComponent”->“ base comp.
  • firstState”->“ first comp.
  • secondState”和“ second comp.

下图更清楚地显示了这种情况:

应用程序组件和状态的层次结构

然后,当用户使用“ wrapperComponent”时,它首先到达“ firstState”,然后他使用“ ”,然后再base state转到“ secondState”,如下图所示:

包装器组件中的状态流

所以,问题是...

所以,问题是当用户到达流程中的第三步时,即当他到达“ secondState”的“”时,“ ”wrapperComponent有时second comp.出现,有时不会出现

目前的调查结果...

Adobe 论坛中的讨论:http ://forums.adobe.com/message/4621058 3

在为此苦苦挣扎了大约两周后,我得出了一个半结论,即不知何故,ActionScript 中的内部事件流已停止。

这意味着,当我的名为“ second comp.”的自定义组件没有出现在屏幕上时:

  • 从“ base state”到“ secondState”的转换被停止/暂停/暂停,
  • 只有“ second comp.”的一些事件被调度(“ preinitialize”、“ initialize”、“ add”、“ added”被调度),但其他一些事件没有被调度:“ addedToStage”和“ creationComplete”未被调度。
  • activeEffects" base comp." 和 " "的变量 " second comp." 包含未播放的效果 (如 "RemoveChildActionInstance" 或 "AddChildActionInstance") 和
  • 这些相同组件的变量“ updateCompletePendingFlag”变量的值为“ true”,表示它们还没有完成更新。

丑陋的黑客

我发现了一个非常可怕的方法来规避这个问题,这个解决方法:

  • 我设置了一个 500 毫秒计时器,当状态必须从“ baseState”变为“ secondState”时开始计数(即上图中从第 2 步到第 3 步)
  • 当这个定时器启动时,我检查组件(即“ base comp.”或“ second comp.”)是否有任何未决的效果,或者它们的“ updateCompletePendingFlag== true”。
  • 如果检查结果为真,那么我会强制调用validateDisplayList()该特定组件上的方法。

代码看起来与此类似:

...
if ( toState == STATE_SECOND ) {
var theTimer    : Timer = new Timer(500,1);
theTimer.stop();
theTimer.addEventListener(
TimerEvent.TIMER_COMPLETE, 
theTimer_complete_Hdl, 
false, 0, true
);
theTimer.start();

currentState = STATE_SECOND ;
}
...

计时器调用此函数:

private function theTimer_complete_Hdl(event:TimerEvent):void
{
if (secondComp.updateCompletePendingFlag)
{

secondComp.invalidateDisplayList();
secondComp.validateDisplayList();
secondComp.validateNow();
this.invalidateDisplayList();
this.validateDisplayList();


}
...
} 

问题...

这真的是肮脏、不雅的代码。另外,它给我的用户体验很差,因为刷新屏幕需要超过一秒钟,而且动作并不迅速。

我的猜测是它在某种程度上对性能产生了负面影响。

**关于可能发生的事情或强制 FlashPlayer 继续播放效果而不是杀死它们并强制更新显示列表的更好方法的任何想法?**

感谢你们!!!:-)

4

1 回答 1

0

我认真地认为这是 FlashPlayer 的错误。

显然,最有可能的答案是这是我的错误,事实上确实如此。

我在这上面花了很多时间,不是因为它很困难,而是因为项目很复杂,而且问题出在一个与有问题的班级没有直接关系的班级中。

在查明原点后,这是一个相当容易的修复。

是什么导致了问题?

除了 myCustomComponent 之外,我还使用了另一个处于先前状态的自定义类(即在“ base comp.”中的“ base state”中)。

customClass扩展了 flex mxLabel类。在commitProperties()被覆盖的方法中,它没有将标志设置为 false,而是invalidateProperties()再次调用。当然,这是一个错误,并且在这个类中引发了一个无限循环(在 " base comp." 组件中有五个实例。

这并没有阻止应用程序继续运行。它并没有阻止它。但它阻止了过渡中定义的效果运行和myCustomComponent实例完成创建。

" " 中出现小错误的伪代码base comp.是这样的:

override protected function commitProperties():void
{
    super.commitProperties();
    if (somethingChanged)
    {
        //1: I wasn't setting somethingChanged=false
        
        //2: I needed to call invalidateProperties() again, like this:
        invalidateProperties();     
    }
}

正确的版本是:

override protected function commitProperties():void
{
    super.commitProperties();
    if (somethingChanged)
    {
        //1: I added this line:
        somethingChanged=false;

        //2: I still need to call invalidateProperties() again, like this:
        invalidateProperties();     
    }
}

甚至更好:

override protected function commitProperties():void
{
    if (somethingChanged)
    {
        //1: I added this line:
        somethingChanged=false;

        //2: Instead of invalidating the properties, doing some  
        //  processing and calling super.commitProperties()
        ...; //  (some processing)
    }
    super.commitProperties();       
}
于 2012-08-28T21:06:06.257 回答