У меня возникла очень странная проблема с Flash и Flex. Похоже, что при определенных обстоятельствах видеоклипы из SWF-файла, загруженного во время выполнения (с использованием Loader), не могут быть созданы, если в это же время был загружен другой SWF-файл. Вот полный код программы, которая воспроизводит ошибку. Он скомпилирован с использованием mxmlc, через Ensemble Tofino :
package
{
import flash.display.*;
import flash.events.*;
import flash.net.*;
import flash.system.*;
public class DynamicLoading extends Sprite
{
private var testAppDomain:ApplicationDomain;
public function DynamicLoading()
{
var request:URLRequest = new URLRequest("http://localhost/content/test.swf");
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onTestLoadComplete);
loader.load(request);
}
private function onTestLoadComplete(e:Event):void
{
var loaderInfo:LoaderInfo = LoaderInfo(e.target);
testAppDomain = loaderInfo.applicationDomain;
// To get the error, uncomment these lines...
//var request:URLRequest = new URLRequest("http://localhost/content/tiny.swf");
//var loader:Loader = new Loader();
//loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onTinyLoadComplete);
//loader.load(request);
// ...and comment this one:
onTinyLoadComplete();
}
private function onTinyLoadComplete(e:Event = null):void
{
var spriteClass:Class = Class(testAppDomain.getDefinition("TopSymbol"));
var sprite:Sprite = Sprite(new spriteClass());
sprite.x = sprite.y = 200;
addChild(sprite);
}
}
}
После второй операции загрузки, закомментированной, как показано выше, код работает. Однако, если вторая операция загрузки не закомментирована и onTinyLoadComplete запускается после загрузки второго SWF-файла, строка, содержащая new spriteClass()
, завершается неудачей со следующим исключением:
TypeError: Error #1034: Type Coercion failed: cannot convert flash.display::MovieClip@2dc8ba1 to SubSymbol.
at flash.display::Sprite/constructChildren()
at flash.display::Sprite()
at flash.display::MovieClip()
at TopSymbol()
at DynamicLoading/onTinyLoadComplete()[C:\Users\...\TestFlash\DynamicLoading.as:38]
test.swf и tiny.swf были созданы во Flash CS4. test.swf содержит два символа, оба экспортированы для ActionScript, один называется TopSymbol, а другой - SubSymbol. SubSymbol содержит простой рисунок (каракули), а TopSymbol содержит один экземпляр SubSymbol. tiny.swf не содержит ничего; это результат публикации нового пустого проекта ActionScript 3.
Если я изменю test.swf, чтобы SubSymbol не экспортировался для ActionScript, ошибка исчезнет, но в нашем реальном проекте нам понадобится возможность динамически загружать классы спрайтов, которые содержат другие экспортируемые классы спрайтов, как дочерние.
Есть какие-нибудь идеи относительно того, что вызывает это, или как это исправить?
Редактировать: Несколько человек предположили, что tiny.swf может содержать класс с тем же именем, что и класс из test.swf или родительский (DynamicLoading.swf). Это не так. Как я уже говорил выше, я сам создал tiny.swf, просто опубликовав новый пустой проект Flash CS4. Вот полный вывод swfdump -D
при запуске на tiny.swf:
[HEADER] File version: 10
[HEADER] File is zlib compressed. Ratio: 41%
[HEADER] File size: 1343
[HEADER] Frame rate: 30.000000
[HEADER] Frame count: 1
[HEADER] Movie width: 550.00
[HEADER] Movie height: 400.00
[045] 4 FILEATTRIBUTES as3 symbolclass
[04d] 1284 METADATA
[009] 3 SETBACKGROUNDCOLOR (ff/ff/ff)
[056] 11 SCENEDESCRIPTION
[001] 0 SHOWFRAME 1 (00:00:00,000)
[000] 0 END