【发布时间】:2013-01-06 01:23:08
【问题描述】:
我有一个类,它使用两个类似的加载器加载两个 swfs(注意新的 ApplicationDomain):
var child1Loader:Loader = new Loader()
child1Loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onChild1Complete)
child1Loader.load(new URLRequest("http://mywebsite.com/assets/load_test/Child1Factory.swf?" + Math.random()), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)))
加载的 swfs 实际上是工厂:
public class Child1Factory extends Sprite
{
public function Child1Factory() {}
public function getChild1():Child1 {
return new Child1()
}
}
加载两个 swf 后,我将 child1 和 child2 添加到舞台,如下所示:
var child1:MovieClip = child1Factory.getChild1()
var child2:MovieClip = child2Factory.getChild2()
addChild(child1)
addChild(child2)
Child1 和 child2 看起来非常相似,但并不完全相同。 Child1 看起来像这样(注意 ADDED_TO_STAGE 监听器):
public class Child1 extends MovieClip
{
public function Child1()
{
Security.allowDomain("*")
if (stage) onAddedToStage(null)
else addEventListener(Event.ADDED_TO_STAGE, onAddedToStage)
}
private function onAddedToStage(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage)
addChild(new MC_CircleGroup())
runChild1Test()
}
private function runChild1Test():void {
var circles:Array = findChildrenOfType(MC_Circle, this)
if (circles.length == 0) {
throw new Error("Oh no!")
}
}
private function findChildrenOfType(type:Class, container:DisplayObjectContainer):Array {
var toReturn:Array = []
for (var childIndex:int = 0; childIndex < container.numChildren; childIndex++) {
var child:DisplayObject = container.getChildAt(childIndex)
if (child is type) {
toReturn.push(child)
} else if (child is DisplayObjectContainer) {
toReturn = toReturn.concat(findChildrenOfType(type, child as DisplayObjectContainer))
}
}
return toReturn
}
}
和 child2 类似,除了将正方形读为圆形。这两个类都有不同的 swcs,其中包含相关的 MC_SquareGroup 或 MC_CircleGroup 影片剪辑。它们中有四个类型为 MC_Square 或 MC_Circle 的孩子。 findChildrenOfType 函数通常返回这四个实例的数组。
错误“没有!”在我运行应用程序的每 5 次中抛出大约 1 次。现在有人为什么吗?或者现在还有更好的解决方法吗?
一些注意事项:
1.) 仅当我通过 Internet 或本地网络加载 swf 时才会引发错误。如果 swf 在同一台计算机上,则不会抛出它。
2.) 加载 child1 但不加载 child2 或 visa virsa 可以正常工作。
3.) 发生错误时,根据我的调试器,MC_CircleGroup 的子级是 MovieClip 类型,而不是 MC_Circle。
4.) 每次运行应用程序时都不会抛出错误。只是每隔几次。为了始终如一地得到错误,我必须在加载两个 swf 后再次调用加载程序来循环加载。
可根据要求提供完整的源代码。
谢谢! 蒂姆
更新
加载器文件中的完整代码如下所示:
public class Main extends Sprite
{
private var child1Factory:Object;
private var child1Loaded:Boolean = false;
private var child2Factory:Object;
private var child2Loaded:Boolean = false;
public function Main():void
{
Security.allowDomain("*")
if (stage) loadChildren();
else addEventListener(Event.ADDED_TO_STAGE, loadChildren);
}
private function loadChildren(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, loadChildren);
child1Loaded = false
child2Loaded = false
var child1Loader:Loader = new Loader()
child1Loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onChild1Complete)
child1Loader.load(new URLRequest("http://mywebsite.com/assets/load_test/Child1Factory.swf?" + Math.random()), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)))
var child2Loader:Loader = new Loader()
child2Loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onChild2Complete)
child2Loader.load(new URLRequest("http://mywebsite.com/assets/load_test/Child2Factory.swf?" + Math.random()), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)))
}
private function onChild1Complete(e:Event):void {
child1Factory = e.currentTarget.content
child1Loaded = true
if (child2Loaded) {
onLoadComplete()
}
}
private function onChild2Complete(e:Event):void {
child2Factory = e.currentTarget.content
child2Loaded = true
if (child1Loaded) {
onLoadComplete()
}
}
private function onLoadComplete():void {
var child1:MovieClip = child1Factory.getChild1()
var child2:MovieClip = child2Factory.getChild2()
addChild(child1)
addChild(child2)
loadChildren(null)
}
}
更新 2 好吧,这变得更加奇怪了。在@DavidMear 之后我更新了它,所以孩子们被添加到 onChildXComplete 函数中,突然间它中断的频率大大降低了。但它仍然偶尔会中断:
public class Main extends Sprite
{
private var child1Factory:Object;
private var child1Loaded:Boolean = false;
private var child2Factory:Object;
private var child2Loaded:Boolean = false;
public function Main():void
{
Security.allowDomain("*")
if (stage) loadChildren();
else addEventListener(Event.ADDED_TO_STAGE, loadChildren);
}
private function loadChildren(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, loadChildren);
child1Loaded = false
child2Loaded = false
var child1Loader:Loader = new Loader()
child1Loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onChild1Complete)
child1Loader.load(new URLRequest("http://mywebsite.com/assets/load_test/Child1Factory.swf?" + Math.random()), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)))
var child2Loader:Loader = new Loader()
child2Loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onChild2Complete)
child2Loader.load(new URLRequest("http://mywebsite.com/assets/load_test/Child2Factory.swf?" + Math.random()), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)))
}
private function onChild1Complete(e:Event):void {
child1Factory = e.currentTarget.content
child1Loaded = true
var child1:MovieClip = child1Factory.getChild1()
addChild(child1)
if (child2Loaded) {
onLoadComplete()
}
}
private function onChild2Complete(e:Event):void {
child2Factory = e.currentTarget.content
child2Loaded = true
var child2:MovieClip = child2Factory.getChild2()
addChild(child2)
if (child1Loaded) {
onLoadComplete()
}
}
private function onLoadComplete():void {
loadChildren(null)
}
}
更新 3
此代码以与原始代码大致相同的频率引发错误,并且堆栈跟踪指向其中一个计时器处理程序。如果没有堆栈跟踪指向 onLoadComplete 的计时器,它也会抛出错误......即测试函数在抛出错误之前已经在 onChildXComplete 函数中成功运行一次。现在我真的很困惑。
public class Main extends Sprite
{
private var child1Factory:Object;
private var child1Loaded:Boolean = false;
private var child2Factory:Object;
private var child2Loaded:Boolean = false;
public function Main():void
{
Security.allowDomain("*")
if (stage) loadChildren();
else addEventListener(Event.ADDED_TO_STAGE, loadChildren);
}
private function loadChildren(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, loadChildren);
child1Loaded = false
child2Loaded = false
var child1Loader:Loader = new Loader()
child1Loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onChild1Complete)
child1Loader.load(new URLRequest("http://mywebsite.com/assets/load_test/Child1Factory.swf?" + Math.random()), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)))
var child2Loader:Loader = new Loader()
child2Loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onChild2Complete)
child2Loader.load(new URLRequest("http://mywebsite.com/assets/load_test/Child2Factory.swf?" + Math.random()), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)))
}
private function onChild1Complete(e:Event):void {
child1Factory = e.currentTarget.content
child1Loaded = true
var child1:MovieClip = child1Factory.getChild1()
addChild(child1)
if (child2Loaded) {
onLoadComplete()
}
}
private function onChild2Complete(e:Event):void {
child2Factory = e.currentTarget.content
child2Loaded = true
var child2:MovieClip = child2Factory.getChild2()
addChild(child2)
if (child1Loaded) {
onLoadComplete()
}
}
private function onLoadComplete():void {
var timer1:Timer = new Timer(500, 1)
timer1.addEventListener(TimerEvent.TIMER_COMPLETE, function(e:TimerEvent):void {
var child1:MovieClip = child1Factory.getChild1()
addChild(child1)
})
timer1.start()
var timer2:Timer = new Timer(1000, 1)
timer2.addEventListener(TimerEvent.TIMER_COMPLETE, function(e:TimerEvent):void {
var child2:MovieClip = child2Factory.getChild2()
addChild(child2)
loadChildren(null)
})
timer2.start()
}
}
【问题讨论】:
-
它间歇性发生并且仅在通过网络加载时发生的事实让我怀疑它与运行测试的时间有关。
Child1可能会在 swf 完全加载之前添加到阶段,那么在onChild1Complete上运行测试会有所不同吗? -
感谢您的回复@DavidMear。我已经用加载器类的完整代码更新了这个问题。在调用 onChild1Complete 之前,不应将 Child1 添加到阶段。我试过明确地分开测试,但不幸的是没有快乐。不过我非常同意你的评价。它似乎没有完全加载。还有其他我可以听的活动吗?
-
嗨@DavidMear。你能看看我上面的第二次更新。越来越奇怪了。你会期望它有不同的表现吗?
-
我现在将原始版本与更新 2 结合起来,因此 child1/child2 被添加到 onChild1Complete/onChild2Complete 上,然后它们都被再次添加到 onLoadComplete 上。发生错误并且堆栈跟踪指向 onLoadComplete 函数。 很奇怪,因为对我来说这意味着它在调用 onChildXComplete 时已经正常工作,所以它必须正确加载。我很混乱。你们认为我应该向 Adobe 提交错误报告吗?
-
哇,更新 2 似乎令人鼓舞,但更新 3 让我很难过。我自己复制了您的最新设置,我可以确认在从服务器加载时每 5 次左右尝试一次从计时器中看到错误。可能值得提交一份带有压缩文件的错误报告以供测试。我会多弄一点,但希望其他人可能有一个想法。
标签: java actionscript-3 flash actionscript loader