ApplicationDomain:错误#1034:实例化类时类型强制失败

时间:2015-02-23 19:17:56

标签: actionscript-3 flash

我做了一个简单的项目来重现这个问题。代码位于说明的底部。

情况:我的应用从网络加载一个swf文件。 swf包含两个简单的按钮类 - ClassA,ClassB和一个PanelC,它包含两个按钮。

当我尝试在加载swf后使用applicationDomain.getDefinition("ClassC")实例化ClassC时,它可以正常工作。

接下来,我加载另一个swf文件,其中包含名为mvFish的类。我尝试实例化它,它也有效。

接下来,我尝试再次快速启动ClassC,它会出错:

[Fault] exception, information=TypeError: Error #1034: Type Coercion failed: cannot convert flash.display::MovieClip@560ed61 to ClassA.

错误不是指我想要实例化的ClassC,而是指其中的ClassA。

更新 - 更改ApplicationDomain无效 - 有关问题的详细信息:

所有类定义仍然可用 - 我可以得到A,B,C或mvFish的定义。

A,B和mvFish仍然可以实例化(因为它们不包含子项)。

C可以实例化其子项是否未作为类导出。

如果它们作为类导出,C会尝试实例化,但是创建其子项(A和B)时会出错。看起来像Movieclip被采用并被强制转换为ClassA并失败。如果我删除A类,则错误发生在B类。它发生在任何子类中。

如果我创建任何类型的ApplicationDomain,请在LoaderContext中使用它,然后尝试从中获取定义,它返回nullgetQualifiedDefinitionNames()给出空列表。仅通过loader属性路径工作,因此看起来加载器在某种程度上具有不同的域。

如果我再次加载第一个swf,问题就会消失。就像每次我需要其他swf的课程一样,我需要重新加载它。

这是第一个swf库看起来的样子,没什么复杂的:

http://i.gyazo.com/ca7473e31331a7dc93d349fa0bb8055c.png

以下是FlashDevelop项目的示例代码:

package {
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.net.URLRequest;
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.system.LoaderContext;
    import flash.system.Security;
    import flash.system.SecurityDomain;
    import flash.system.ApplicationDomain;
    import flash.display.Sprite;

    public class Main extends Sprite {

        private var asset:Loader;
        private var lc:LoaderContext = new LoaderContext(true, ApplicationDomain.currentDomain);

        public function Main():void {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }

        private function init(e:Event = null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            Security.allowInsecureDomain("*");
            Security.allowDomain("*");
            var l:Loader = new Loader();
            l.contentLoaderInfo.addEventListener(Event.COMPLETE, firstComplete);
            // loading first asset
            l.load(new URLRequest("http://zdg.ru/tmp/test_asset.swf"), lc);
        }

        private function firstComplete(evt:Event):void {
            asset = evt.target.loader;
            var mc:Class = asset.contentLoaderInfo.applicationDomain.getDefinition("ClassC") as Class;
            new mc() as Sprite; // trying to instantiate ClassC -- OK!
            var l:Loader = new Loader();
            l.contentLoaderInfo.addEventListener(Event.COMPLETE, secondComplete);
            // loading the second asset
            l.load(new URLRequest("http://zdg.ru/tmp/Fish.swf"), lc);
        }

        private function secondComplete(evt:Event):void {
            var mc:Class = evt.target.applicationDomain.getDefinition("mvFish") as Class;
            new mc() as Sprite; // trying to instantiate mvFish -- OK!
            mc = asset.contentLoaderInfo.applicationDomain.getDefinition("ClassC") as Class;
            new mc() as Sprite; // trying to instantiate ClassC again -- Error!
        }
    }
}

1 个答案:

答案 0 :(得分:0)

这不是一个真正的aswer,但我发布的代码昨天没有工作,但它今天神奇地起作用。 - 更新 - 哦,忘掉它,它不起作用。

最后,我找到了原因。它没有严格的工作原因有两个:

1)ClassC包含ClassA,它是一个SimpleButton。是的,只有按钮是坏的,只有那些包含在其他DisplayObjects中的按钮。使它成为MovieClip,它将工作。直接在没有容器的情况下实例化按钮,它也可以工作。

2)项目在本地运行。把它放到主机上它会像魅力,按钮或其他任何东西一样工作。

所以最后一个问题:如何设置FlashDevelop以在本地处理加载的资产?