【问题标题】:How to run an external SWF inside a Flex Application?如何在 Flex 应用程序中运行外部 SWF?
【发布时间】:2010-04-26 13:40:35
【问题描述】:

编辑:由于答案,我更改了发布的代码。我已经添加了 Security.allowDomain("*") 行,那行给我一个错误。那么,如何制作呢?

我想将 Action Script 3.0 应用程序运行到 Flex 应用程序中。为此,我做了以下工作:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication windowComplete="loadSwfApplication()" xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Script>
        <![CDATA[
            private function loadSwfApplication()
            {
                // The next line throws me an error.
                Security.allowDomain("*");

                var urlRequest:URLRequest = new URLRequest("path/to/the/application.swf");
                swfLoader.addEventListener(Event.COMPLETE, loadComplete);
                swfLoader.load(urlRequest);
            }

            private function loadComplete(completeEvent:Event)
            {
                var swfApplication:* = completeEvent.target.content;
                swfApplication.init();  // this is a Function that I made it in the Root class of swfApplication
            }
        ]]>
    </mx:Script>

    <mx:SWFLoader id="sfwLoader"/>

</mx:WindowedApplication>

问题是在调用swfApplication.init(); 时,AIR Player 会抛出异常:

安全沙盒违规:调用方文件:///path/to/the/application.swf 无法访问 app:/SWFApplicationLoader.swf 拥有的 Stage。

这是因为在application.swf的某处我使用这样的舞台:

if (root.stage != null)
    root.stage.addEventListener(Event.REMOVED, someFunction);
root.stage.stageFocusRect = false;

如何加载此 swf 应用程序并毫无问题地使用舞台?

【问题讨论】:

    标签: actionscript-3 flash air flex4


    【解决方案1】:

    您可以尝试将您的SWF 临时加载到ByteArray 中,然后将其与您的SWFLoader 一起加载。

    不要忘记将allowCodeImport 设置为true,因为您的SWF 内部有as 代码。

    当然要确保您加载的 swf 对于您的应用程序来说足够安全,因为它可以访问您的所有财产。

    private function loadSwfApplication():void {
      // load the file with URLLoader into a bytearray
      var loader:URLLoader=new URLLoader();
    
      // binary format since it a SWF
      loader.dataFormat=URLLoaderDataFormat.BINARY;
      loader.addEventListener(Event.COMPLETE, onSWFLoaded);
    
      //load the file
      loader.load(new URLRequest("path/to/the/application.swf"));
    }
    private function onSWFLoaded(e:Event):void {
     // remove the event
     var loader:URLLoader=URLLoader(e.target);
     loader.removeEventListener(Event.COMPLETE, onSWFLoaded);
    
     // add an Application context and allow bytecode execution 
     var context:LoaderContext=new LoaderContext();
     context.allowCodeImport=true;
    
     // set the new context on SWFLoader
     sfwLoader.loaderContext = context;
    
     sfwLoader.addEventListener(Event.COMPLETE, loadComplete);
    
     // load the data from the bytearray
     sfwLoader.load(loader.data);
    }
    
    // your load complete function
    private function loadComplete(completeEvent:Event):void {
     var swfApplication:* = completeEvent.target.content;
     swfApplication.init();  // this is a Function that I made it in the Root 
                             // class of swfApplication
    }
    

    【讨论】:

    • 这也适用于移动平台吗?如果是,你可以为 iOS 写一个 Flash 播放器。
    • 知道为什么这适用于字节数组而不适用于 swfloader 组件吗?
    【解决方案2】:

    如果它们是从不同的域加载的,您将不得不添加一个安全异常 - http://livedocs.adobe.com/flex/3/html/help.html?content=05B_Security_08.html

    如果它在本地运行,您可能必须将它们添加到设置管理器中的受信任文件或文件夹列表中 - http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html#117502

    【讨论】:

    • 当我尝试添加安全异常时,它会抛出一个错误:SecurityError: Error #3207: Application-sandbox content cannot access this feature. at flash.system::Security$/allowDomain()
    • 并且它已经添加到设置管理器中的受信任文件中。
    【解决方案3】:

    假设外部 SWF 也在应用程序目录中,您可以尝试使用 app:/ 方案加载它:

    var urlRequest:URLRequest = new URLRequest("app:/path/application.swf");
    

    这可能会将其置于与主应用程序相同的安全上下文中。

    【讨论】:

      【解决方案4】:

      您可能需要考虑的一件事是,如果您尝试从 AIR 中的应用程序目录内运行 SWF,AIR 会限制文件的执行。如果您将文件复制到临时文件并运行它(以及将allowLoadBytesCodeExecution 设置为true),那么它可以工作。

      var file:File = File.applicationDirectory.resolvePath("myFile.swf");
      this.tmpFile = File.createTempDirectory().resolvePath("myFile.swf");
      file.copyTo(this.tmpFile);
      
      imagePreview.loaderContext = lc;
      imagePreview.source = tmpFile.url;
      

      【讨论】:

        【解决方案5】:

        它不适用于 Flex 投影仪。

        我们只使用 SWFLoader 和 LocalConnection,因为它们可以在外部 swf 和主 swf 之间进行通信。感谢支持!

        你能看一下Adobe's Forum我的教程吗

        它比 MovieClip 或 Object-Callers 好很多

        感谢您的解决方案:)

        最好的问候,詹斯

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-06-04
          • 2014-04-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多