简体   繁体   中英

Create Plugins in Flex - loading nested SWF files

I'm trying to implement a plugin system for our application, and having a devil of a time getting SWF file which was dynamically loaded itself, load additional SWF files.

It goes something like this:

  1. Main Application Shell loads...
  2. ---------+ Application loads...
  3. -----------------+Plugin(s)

I have no problem getting app #1 to load app #2

However, try as I might, I cannot get app #2 to load and instantiate #3

I've tried various permutations using the ModuleManager, but this is the closest I get. When the onLoadComplete method get invoked, I can see that the SWF loaded, however the factory always returns NULL.

What is interesting is that when I extract this out in its own application, it works fine. This issue is triggered by the fact that I'm loading Plugin from a SWF that was loaded dynamically itself.

I believe this is due to the ApplicationDomain , but I cannot make heads or tails of it. I tried specifying currentDomain , new ApplicationDomain(Application.currentDomain) and new ApplicationDomain() without success.

Also, it is important to note that I cannot make reference a hard reference to the Foo class in either applications since by their nature, we will not know ahead of time what they will contain.

Googlin' around, this seems to be a fairly known problem, but I have not found a (clear) solution yet.

.
.
.
assetModule = ModuleManager.getModule("Foo.swf");    
assetModule.addEventListener(ModuleEvent.READY, onLoadComplete );
assetModule.addEventListener(ModuleEvent.ERROR, onLoadError);
assetModule.load();
.
.
.
private var _pluginInstance:Plugin;

private function onLoadComplete( event:Event ):void
{
    trace("module loaded");

    _pluginInstance = assetModule.factory.create() as Plugin;
    if( _pluginInstance )
        _pluginInstance.startup();
    else 
        Alert.show("unable to instantiate module");
}

private function onLoadError( event:Event ):void
{
       Alert.show("error");
}

My Plugin looks like this:

package
{
    import mx.collections.ArrayCollection;
    import mx.modules.ModuleBase;

        public class Plugin extends ModuleBase

        public function startup():void
        {

        }
.
.
.
}

and

package 
{
    import Plugin;
    import mx.modules.ModuleBase;

    public class Foo extends Plugin
    {
        public function Foo()
        {
            trace("foo constructor invoked");
        }

        override public function startup():void
        {
                    trace("foo started");
        }
.
.
.
}

If you really want to use a common interface between your plugin and your application, your application's Plugin class must be the same as your plugin's Plugin class. To do so, they need b to be in the same ApplicationDomain.

//In an external library
public interface Plugin {}

//In your application
_pluginInstance = assetModule.factory.create() as Plugin;
...


//In your plugin
public class MyPlugin implements Plugin

The problem is, when you will compile your plugin swf, you will also compile Plugin. This is not a problem, but you need to tell your application that it's the same as his :

var loader:Loader = new Loader();
loader.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest("plugin.swf"), new LoaderContext(false, ApplicationDomain.currentDomain));    

ApplicationDomain.currentDomain is the key here. If you refer to the docs :

Loader's own ApplicationDomain. You use this application domain when using ApplicationDomain.currentDomain. When the load is complete, parent and child can use each other's classes directly. If the child attempts to define a class with the same name as a class already defined by the parent, the parent class is used and the child class is ignored.

@ joshtynjala is right. I found try just using Object then calling methods on it (don't cast).

var MyPlugin : Object = getPlugin(); MyPlugin.doPluginFunc();

Generally can cast between system/flex classes no problem. Don't know if putting Plugin as a runtime library would help ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM