Actionscript 3: проблема с загрузкой внешнего SWF
У меня возникли проблемы с попыткой загрузить внешне определенные классы в actionscript 3.0. Я полагаю, что это проблема моего понимания классов ApplicationDomain / LoaderContext, но даже после просмотра документации и нескольких поисков в Интернете я все еще застрял.
По сути, я хочу загрузить SWF, содержащий символ, который является реализацией интерфейса, совместно используемого вызывающим SWF и загруженным SWF. Я могу нормально загрузить swf, а также создать и выполнить на нем методы, но только до тех пор, пока не попытаюсь привести его к общему типу интерфейса. Если я пытаюсь его привести, я получаю ошибку TypeError: Error #1034: Ошибка приведения типа: ошибка типа.
Я подозревал, что это потому, что при загрузке нового класса flash распознает его как совершенно другой класс, отсюда и исключение. В документации предлагается использовать аргумент LoaderContext, для которого для applicationDomain установлено значение ApplicationDomain.currentDomain.
Проблема в том, что это не имеет никакого эффекта. Независимо от того, установлен ли для ApplicationDomain значение currentDomain, null или дочерний элемент текущего домена, я все равно получаю ошибку приведения типа. Кажется, что:: часть ошибки указывает на то, что загруженный класс находится в другом пространстве имен или где-то еще, когда я хочу, чтобы он находился в том же пространстве имен, что и мой загрузчик.
Код:
import flash.display.Loader;
import flash.display.MovieClip;
import flash.events.Event;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
public class TestSkin extends MovieClip
{
var mLoader:Loader;
public function TestSkin()
{
super();
startLoad("ExternalTest.swf");
}
private function startLoad(url:String):void
{
mLoader = new Loader();
var mRequest:URLRequest = new URLRequest(url);
var appDomain:ApplicationDomain = ApplicationDomain.currentDomain;
//Loading into different domains seems to have no effect
//var appDomain:ApplicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
//var appDomain:ApplicationDomain = null;
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
mLoader.load(mRequest, new LoaderContext(false, appDomain));
}
private function onCompleteHandler(loadEvent:Event):void
{
//Get the object from the loadEvent
var obj:Object = loadEvent.target.content;
//Verify that the methods exist on the object
trace("Loaded item id: " + obj.getInterfaceId());
//This returns Loaded item id: ExternalTestInterfaceImplementation!
//Try assigning as an instance of the shared type - fails with type coercion error
//Throws the following type error:
//TypeError: Error #1034: Type Coercion failed: cannot convert myPackage::ExternalTestInterfaceImplementation@257b56a1 to myPackage.TestInterface.
var castItem:TestInterface = TestInterface(obj);
trace("castItem: " + castItem);
}
}
Объявление интерфейса:
public interface TestInterface
{
function getInterfaceId():String;
}
Реализация интерфейса
public class ExternalTestInterfaceImplementation extends MovieClip implements TestInterface
{
public function getInterfaceId() : String
{
return "ExternalTestInterfaceImplementation!";
}
public override function toString():String
{
return getInterfaceId();
}
}
1 ответ
Похоже, это вызвано ошибкой в плеере. Я столкнулся с этой же проблемой некоторое время назад. Это описано здесь:
https://bugs.adobe.com/jira/browse/ASC-3529
Существует обходной путь, который в основном заключается в загрузке SWF с URLLoader
(в двоичном виде), а затем с помощью Loader::loadBytes
(вместо того, чтобы просто использовать обычный Loader
).
Вот объяснение этого обходного пути и класса загрузчика, который исправляет эту проблему: