There are a couple of things there.

Firstly, AIR is really funny about loading "remote" content that
contains executable code (ref : My arguments with Alex previously).

It wants to load content from the application directory (I know this is
true for modules at least), so you may have more luck loading your swfs
from the application directory.

 

The issue about only every seeming to load the first one, it actually is
a garbage collection issue, but not the swf loader, it's the classes you
load in. Flex uses a "First class wins" method of loading in content, so
if you add a TestClass to the application domain, and then a totally
different TestClass to the same domain, only the first one ever gets
used, even if the classes have been loaded by totally different loaders.

 

Its explained more clearly (at least more clearly than I can) in the
livedocs and on Alex's website.

http://livedocs.adobe.com/flex/3/html/help.html?content=18_Client_System
_Environment_5.html

http://blogs.adobe.com/aharui/

 

Hope this helps even a little (It usually bewilders me!)

 

Gk.

Gregor Kiddie
Senior Developer
INPS

Tel:       01382 564343

Registered address: The Bread Factory, 1a Broughton Street, London SW8
3QJ

Registered Number: 1788577

Registered in the UK

Visit our Internet Web site at www.inps.co.uk
<blocked::http://www.inps.co.uk/> 

The information in this internet email is confidential and is intended
solely for the addressee. Access, copying or re-use of information in it
by anyone else is not authorised. Any views or opinions presented are
solely those of the author and do not necessarily represent those of
INPS or any of its affiliates. If you are not the intended recipient
please contact [EMAIL PROTECTED]

________________________________

From: [email protected] [mailto:[EMAIL PROTECTED] On
Behalf Of Francis Potter
Sent: 01 October 2008 00:53
To: [email protected]
Subject: [flexcoders] Frame scripts problem, loading using ByteArray,
with document base class, in AIR

 

I'm a lurker / first-time poster to this list but this is an advanced
issue. I think may be a bug in the Player or Flash libraries but maybe
I'm missing something.

I have an AIR application which needs to load multiple SWFs from the
filesystem. Once the SWFs are loaded, the AIR application needs to (1)
call a single method on the document base class of the SWF, then (2)
play the SWF such that the timeline displays correctly and the frame
scripts execute correctly.

The SWFs are authored in Flash CS3 and have a document base class,
which they all share. The base class implements an interface. The AIR
application knows about the interface. So it casts the MovieClip to
the interface to call the method.

If the AIR application loads the SWF file directly from the filesystem
(i.e. by passing the file path or a file:// URL into SWFLoader) then I
can't find a way to make the interface cast work. I get a "Security
sandbox violation" error. That seems to be consistent with the
documentation which says "Content in the air application security
sandbox cannot load content from other sandboxes into its
SecurityDomain." (In general, I find the security sandbox
documentation to be very confusing, but my interpretation is that this
is not expected to work.)

The workaround is to load the SWF myself into a ByteArray, then use
allowCodeBytesExecution to permit me to call methods, etc.

I have a SWFLoader that looks like this:

<mx:SWFLoader id="mySWFLoader" autoLoad="false"
visible="true" scaleContent="false" trustContent="true"
complete="onSWFLoaderComplete(event);"/>

First my AIR application sets up the LoaderContext for the SWFLoader:

var newDomain:ApplicationDomain = new ApplicationDomain();
var myDomain:ApplicationDomain = ApplicationDomain.currentDomain;
var childDomain:ApplicationDomain = ApplicationDomain(childDomain);
var loaderContext:LoaderContext = 
new LoaderContext(false, childDomain);
loaderContext.allowLoadBytesCodeExecution = true;
this.mySWFLoader.loaderContext = loaderContext;

Then I just load the SWF using AIR's FileStream class:

var file:File = new File(path);
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);
var byteArray:ByteArray = new ByteArray();
fileStream.readBytes(byteArray);
fileStream.close();

Then I poke the content into the SWFLoader:

this.mySWFLoader.load(byteArray);

And, once loading is complete, I execute the cast:

private function onSWFLoaderComplete(event:Event):void {
try {
var myChild:ITestInterface =
ITestInterface(this.mySWFLoader.content);
myChild.someMethod();
trace('Coersion to ITestInterface SUCCESSFUL');
} catch (e:Error) {
trace('Coersion to ITestInterface UNSUCCESSFUL');
}
}

This WORKS. Both of the things I amy trying to accomplish are
successful. (1) I am able to call the method someMethod() which is
defined in the interface and implemented in the document base class of
the SWF; and (2) when the SWF plays (which happens automatically once
it's loaded) it appears correctly on the stage, and the frame scripts
in the SWF execute correctly (I can verify in trace output).

HOWEVER, the NEXT time I load a SWF, something very strange happens.
The cast works, the method is called, the SWF is loaded and plays
correctly. __But it uses the frame scripts from the previous script,
not its own__.

So here's the sequence:
(1) Load SWF A
(2) SWF A is displayed correctly on the stage
(3) I am able to call someMethod on SWF A
(4) SWF A's frame scripts execute correctly
(5) Load SWF B
(6) SWF B is displayed correctly on the stage
(7) I am able to call someMethod on SWF B
(8) SWF A's frame scripts execute, but usually break because
they are looking for symbols, etc. which aren't there.
The frame scripts defined on SWF A are trying to execute
in the context of SWF B.

Note that this does NOT appear to be a garbage collection issue
related to sharing the SWFLoader. Even if I use an entirely different
SWFLoader, the problem persists.

Furthermore, it ONLY persists if the SWFs share *Document Base Classes
of the same name*. If the Document Base Classes have different names
(but are identical code, implementing the same interface) then it
works fine.

I have read that frame scripts are actually handled as methods on the
MovieClip itself -- which makes sense. And what I am imagining
happening is that, when a loaded SWF has a document base class, those
methods are being applied to the base class *and all successive SWFs
loaded that use a document base class of the same name*. This seems
completely wrong. The SWFs are, in a sense *instances* of the base
class which could quite sensibly have different frame scripts. So I
*think* what's happening is that Flash Player is keeping some registry
of classes; when it loads a SWF it also loads the definition of the
class; it's adding the methods for the frame scripts to the definition
of the class; and when it loads another SWF with a base class of the
same name, it sees that it already "has" the definition and doesn't
bother looking at the frame scripts in the newly loaded SWF.

I keep thinking I'm way off base, and that there must be some simple
solution, but I really can't find it. 

Does *anyone* have any experience that might help?

Cheers,

Francis

 

Reply via email to