java - flash.display.Loader 间歇性地导致加载的 swf 的子项松散类型

标签 java actionscript-3 flash actionscript loader

我有一个类使用两个类似于这个的加载器加载两个 swf(注意新的 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)))

加载的 swf 实际上是工厂:

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 类似,只是读方换圆。这两个类都有不同的 swc,其中包含相关的 MC_SquareGroup 或 MC_CircleGroup 动画片段。它们有四个 MC_Square 或 MC_Circle 类型的 child 。 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 之后,我更新了它,以便将 child 添加到 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()          

    }

}

最佳答案

我认为 findChildrenOfType 方法可能不太适合递归调用,因为您在每次调用时都会重置 toReturn 数组。也许这样的事情可能会更好?

function findChildrenOfType(type:Class, container:DisplayObjectContainer, toReturn:Array = null ):Array {
    if(!toReturn) toReturn = [];
    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) {
            findChildrenOfType( type, child as DisplayObjectContainer, toReturn );
        }
    }
    return toReturn;
}

关于java - flash.display.Loader 间歇性地导致加载的 swf 的子项松散类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14464898/

相关文章:

java - 在 Java 中比较对象的更优雅的方式

javascript - 通过 $.ajax() 发送表单元素和数组

actionscript-3 - 查找实际的文字高度AS3

javascript - 为什么 swfobject 不加载 flash div?

html - CreateJS - 针对特定关键帧

java - 需要帮助来简化解决方案

java - 在 Jboss Wildfly 上部署 EAR 文件时失败

javascript - 从 Javascript 调用 Flex/AS3 回调

actionscript-3 - 对象类型和字典类型中的映射对象有什么区别

apache-flex - 如何批量将swf转成flv