Как я могу загрузить Adobe Alchemy SWF построить динамически

С Алхимией большинство сборок являются статическими сборками SWC. Они отлично подходят для прямой связи с библиотекой, но если вы пытаетесь использовать более одной библиотеки за раз, вы обычно (всегда?) Сталкиваетесь с проблемами с общим пространством памяти. Одно из решений, о которых я читал, состоит в том, чтобы вместо этого создавать SWF-файлы и загружать их динамически в их собственный ApplicationDomain. Это даст всем библиотекам собственную память и позволит вам загружать несколько библиотек Алхимии. (Как уже упоминалось в этих темах на форумах Adobe: http://forums.adobe.com/message/3665801 и http://forums.adobe.com/message/3927791)

Мой вопрос: как мне загрузить эти SWF-файлы и получить код внутри них? Кажется, нет никакой документации по этому вопросу, и хотя я знаю, как загрузить SWF, я не знаю, как добраться до кода, потому что у меня нет никакого интерфейса к SWF.

2 ответа

Решение

Проблема в том, что мы хотим динамически загружать библиотеку Alchemy, но если мы собираем библиотеку как SWF-файл, она не будет работать (так как это создает отдельное приложение). Но мы не можем динамически загрузить SWC- или мы можем?

Вот что нужно сделать (при условии, что библиотека с именем mylib):

  1. строить mylib как SWC.
  2. расстегнуть молнию mylib.swc и извлечь library.swf файл; переименуйте его в mylib.swf
  3. встраивать mylib.swf как бинарный актив
  4. Во время выполнения создайте экземпляр актива как ByteArray
  5. Передать актив ByteArray Загрузчику #loadBytes
  6. Когда загрузчик запускает COMPLETE, используйте Loader#contentLoaderInfo, чтобы получить ApplicationDomain загруженного SWF
  7. Используйте ApplicationDomain#getDefinition, чтобы найти класс инициализатора Alchemy. например, cmodule.mylib.CLibInit
  8. Используйте инициализатор, как обычно. например, позвонить init, так далее.
  9. ... прибыль!

Таким образом, вы можете встроить произвольное количество библиотек Alchemy, каждая из которых работает в своем собственном домене приложений.

Я пытался загрузить библиотеку динамически, создав новый домен ApplicationDomain и передав его в контекст загрузчика для загрузки. Что я делал неправильно, так это сохранял ссылку на этот ApplicationDomain и пытался получить определение из этой ссылки. По какой-то причине это возвращало ноль. Реализуя ответ 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();
        }
    }        
}

А вот код, если вы хотите встроить его (ответ палеозогта):

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();
        }
    }
}
Другие вопросы по тегам