0

对于 Alchemy,大多数构建都是静态 swc 构建。这些对于直接链接库非常有用,但是如果您尝试一次使用多个库,您通常(总是?)会遇到共享内存空间的问题。我读过的一种解决方案是构建 swf 并将它们动态加载到它们自己的 ApplicationDomain 中。这将为所有库提供自己的内存,并允许您加载多个 Alchemy 库。(如 adobe 论坛上的这些主题所述:http: //forums.adobe.com/message/3665801http://forums.adobe.com/message/3927791

我的问题是:如何加载这些 swf 并获取其中的代码?似乎没有关于这个问题的任何文档,虽然我知道如何加载 swf,但我不知道如何获取代码,因为我没有任何与 swf 的接口。

4

2 回答 2

0

问题是我们想要动态加载 Alchemy 库,但如果我们将库构建为 SWF,它将无法工作(因为这会生成一个独立的应用程序)。但是我们不能动态加载 SWC——或者我们可以吗?

这是要做的事情(假设一个名为 的库mylib):

  1. 构建mylib为 SWC。
  2. 解压mylib.swc并解压library.swf文件;将其重命名为mylib.swf
  3. 嵌入mylib.swf二元资产
  4. 在运行时,将资产实例化为ByteArray
  5. 将资产传递ByteArrayLoader#loadBytes
  6. 当加载器触发 COMPLETE 时,使用Loader#contentLoaderInfo获取加载的 SWF 的 ApplicationDomain
  7. 使用ApplicationDomain#getDefinition查找 Alchemy 初始化程序类。例如,cmodule.mylib.CLibInit
  8. 像往常一样使用初始化程序。例如,呼叫init等。
  9. ...利润!

您可以通过这种方式嵌入任意数量的 Alchemy 库,每个库都在自己的 ApplicationDomain 中运行。

于 2012-08-22T15:36:32.360 回答
0

我一直试图通过创建一个新的 ApplicationDomain 并将其传递给加载程序上下文来动态加载库。我做错的是存储对该 ApplicationDomain 的引用并尝试从该引用中获取定义。出于某种原因,它返回 null。通过实现paleozogt的答案并改变它以动态加载swf,我最终得到了正确的代码,它不使用对ApplicationDomain的存储引用,而是从加载器的contentLoaderInfo中获取它。

如果你想动态加载库,下面是代码:

package
{
    import flash.display.Loader;
    import flash.events.Event;
    import flash.net.URLRequest;
    import flash.system.ApplicationDomain;
    import flash.system.LoaderContext;

    public class AlchemyDynamicLoad
    {
        private var _library:Object;
        private var _loader:Loader;

        public function AlchemyDynamicLoad()
        {
            var loaderContext:LoaderContext = new LoaderContext(false, new ApplicationDomain());
            var request:URLRequest = new URLRequest("../assets/mylib.swf");
            _loader = new Loader();
            _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
            _loader.load(request, loaderContext);
        }

        private function completeHandler(event:Event):void
        {
            // NOTE: Storing a reference to the application domain you feed to the loaderContext and then trying to get the 
            // definition from that reference is not going to work for some reason. You have to get the applicationDomain
            // from the contentLoaderInfo, otherwise getDefinition returns null.
            var libClass:Class = Class(_loader.contentLoaderInfo.applicationDomain.getDefinition("cmodule.mylib.CLibInit"));
            _library = new libClass().init();
        }
    }        
}

如果你想嵌入它,这里是代码(paleozogt's answer):

package
{
    import flash.display.Loader;
    import flash.events.Event;

    public class AlchemyStaticLoad
    {
        [Embed(source="../assets/mylib.swf", mimeType="application/octet-stream")]
        private static var _libraryClass:Class;

        private var _library:Object;
        private var _loader:Loader;

        public function AlchemyStaticLoad()
        {
            _loader = new Loader();
            _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
            _loader.loadBytes(new _libraryClass());
        }

        private function completeHandler(event:Event):void
        {
            var libClass:Class = Class(_loader.contentLoaderInfo.applicationDomain.getDefinition("cmodule.mylib.CLibInit"));
            _library = new libClass().init();
        }
    }
}
于 2012-08-23T07:51:06.350 回答