我有点问题。
环境:Flex 3(实际更新为Flex 4 SDK,但仍使用 mx 而不是 spark )
IDE:Flash Builder 4.6。
浏览器:Firefox 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.
”
“updateCompletePendingFlag
”包含未播放的效果(例如
“RemoveChildActionInstance”或“AddChildActionInstance”)和true
”变量
组件的值是“baseState
”,意味着它们还没有完成
更新。我找到了一种绕过问题的非常可怕的方法,解决了这个问题:
secondState
”更改为“base comp.
”时(即,从上图中的步骤2到步骤3),计时器开始计数< / LI>
second comp.
”或“updateCompletePendingFlag
”)是否有任何待处理效果或“true
== { {1}}”。 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继续播放效果而不是杀死它们并强制执行updateDisplayList的更好方法吗?**
谢谢你们!!! : - )
答案 0 :(得分:0)
我认真地认为这是FlashPlayer的错误。
显然,最可能的答案是,这确实是我的错误。
我花了很多时间在这上面,不是因为它很难,而是因为项目很复杂,问题出在一个与问题不直接相关的课程中。
在查明原点之后,这是一个相当容易的修复。
我和myCustomComponent一起使用了之前状态中的另一个自定义类(即“base comp.
”中的“base state
”)。
此customClass
扩展了flex mx Label
类。在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();
}