Как я могу загрузить 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
):
- строить
mylib
как SWC. - расстегнуть молнию
mylib.swc
и извлечьlibrary.swf
файл; переименуйте его вmylib.swf
- встраивать
mylib.swf
как бинарный актив - Во время выполнения создайте экземпляр актива как
ByteArray
- Передать актив
ByteArray
Загрузчику #loadBytes - Когда загрузчик запускает COMPLETE, используйте Loader#contentLoaderInfo, чтобы получить ApplicationDomain загруженного SWF
- Используйте ApplicationDomain#getDefinition, чтобы найти класс инициализатора Alchemy. например,
cmodule.mylib.CLibInit
- Используйте инициализатор, как обычно. например, позвонить
init
, так далее. - ... прибыль!
Таким образом, вы можете встроить произвольное количество библиотек 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();
}
}
}