Call an Adobe Flex/ActionScript method from JavaScript?

做~自己de王妃 提交于 2020-01-06 08:04:08

问题


I need to know why JavaScript can't talk back to Flex. I have a project that is going to use JavaScript to play a given video file. Its running on a custom MVC framework where asset files are loaded via the /static prefix.

Example: http://helloworld/static/swf/movie.swf`

I compile my Flex application using the mxmlc binary with options -static-link-runtime-shared-libraries=true, -use-network=true and --debug=true.

Flex

<?xml version="1.0" encoding="utf-8"?>
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    creationComplete="init()">
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import flash.external.ExternalInterface;
            private function init():void {
                log("Logging...");
                if (ExternalInterface.available) {
                    ExternalInterface.call("HelloWorld.initFlash");
                    ExternalInterface.addCallback("playVideo", playVideo);
                }
            }
            public function playVideo():void {
                log("Playing video...");
            }
            public function log(message:String):void {
                if (ExternalInterface.available) {
                    ExternalInterface.call(
                        "function log(msg){ if (window.console) { console.log(msg); } }", 
                        message);
                }
            }
        ]]>
    </fx:Script>
    <s:Panel id="myPanel" title="Hello World" x="20" y="20">
        <s:layout>
            <s:HorizontalLayout 
                paddingLeft="10"
                paddingRight="10"
                paddingTop="10"
                paddingBottom="10"
                gap="5" />
        </s:layout>       
    </s:Panel>
</s:Application>

HTML

<!DOCTYPE HTML>
<html lang="en-US">
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
        <script type="text/javascript">
            $(function(){
                var swfVersionStr        = "10.1.0";
                var xiSwfUrlStr          = "playerProductInstall.swf";
                var flashvars            = {};
                var params               = {};
                var attributes           = {};
                params.allowscriptaccess = "sameDomain";
                params.quality           = "high";
                params.bgcolor           = "#FFFFFF";
                params.allowfullscreen   = "true";
                attributes.id            = "HelloWorld";
                attributes.name          = "HelloWorld";
                attributes.align         = "left";
                swfobject.embedSWF( 
                    "HelloWorld.swf", 
                    "flash-content", 
                    "100%", "100%", 
                    swfVersionStr, xiSwfUrlStr, flashvars, params, attributes ); 
                HelloWorld = function(){
                    return {
                        initFlash : function() {
                            console.log("Called from Flex...");
                            console.log($("#HelloWorld").get(0).playVideo("be6336f9-280a-4b1f-a6bc-78246128259d"));
                        }
                    }
                }();
            });
        </script>
        <style type="text/css">
            #flash-content-container {
                width  : 400px;
                height : 300px;
            }
        </style>
    </head>
    <body>
        <div id="layout">
            <div id="header"><h1>Hello World</h1></div>
            <div id="flash-content-container">
                <div id="flash-content"></div>
            </div>
        </div>
    </body>
</html>

Output

Logging...
Called from Flex...

回答1:


I had the same issue, in the link provided by Chris Cashwell it shows the base for the solution.

Flex MXML

    <?xml version="1.0" encoding="utf-8"?>
    <s:Application 
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        creationComplete="init()">
        <fx:Script>
            <![CDATA[
                import mx.controls.Alert;
                import flash.external.ExternalInterface;
                private function init():void {
                    consoleLog("Hello World");
                    try 
                    {  
                        Security.allowDomain("*"); //I need to add this.
                        ExternalInterface.marshallExceptions = true;
                        ExternalInterface.addCallback("sendAlert",sendAlert);
                        ExternalInterface.call("initCallBack");
                    }  catch (error:Error) {
                        consoleLog("Error in ExternalInterface");                           
                        consoleLog("Error" + error.message);
                    }
                }
                public function sendAlert(s:String):void
                {
                    Alert.show(s);
                }
                public function consoleLog(message:String):void {
                    if (ExternalInterface.available) {
                        ExternalInterface.call(
                            "function log(msg){ if (window.console) { console.log(msg); } }", 
message);
                    }
                }
            ]]>
        </fx:Script>
        <s:Panel id="panel1" title="Hello World" x="20" y="20">
            <s:layout>
                <s:HorizontalLayout 
                    paddingLeft="10"
                    paddingRight="10"
                    paddingTop="10"
                    paddingBottom="10"
                    gap="5" />
            </s:layout>
            <s:TextArea id="textarea1" 
                width="300" height="100" 
                text="Hello World" />       
        </s:Panel>
    </s:Application>

HTML

<!DOCTYPE HTML>
<html lang="en-US">
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
        <script type="text/javascript">
            var flexApp;
            function initCallBack() {  
                flexApp = document.getElementById("HelloWorldFlex");
                if (flexApp != undefined) { 
                   try {
                      flexApp.sendAlert( "Hello World" );
                   } catch(err) {
                      console.log("There was an error on the flex callback.");
                      console.log(err);     
                   }
                } else {
                    console.log("The flex object does not exist yet");
                }
                return;
            } 
            $(function(){
                HelloWorld = function(){
                    return {
                        init : function() {
                            var swfVersionStr        = "10.1.0";
                            var xiSwfUrlStr          = "playerProductInstall.swf";
                            var flashvars            = {
                                bridgeName : "flex",
                            };
                            var params               = {};
                            var attributes           = {};
                            params.allowscriptaccess = "always";
                            params.quality           = "high";
                            params.bgcolor           = "#FFFFFF";
                            params.allowfullscreen   = "true";
                            attributes.id            = "HelloWorldFlex";
                            attributes.name          = "HelloWorldFlex";
                            attributes.align         = "left";
                            swfobject.embedSWF( 
                                "HelloWorld.swf", 
                                "flash-content", 
                                "100%", "100%", 
                                swfVersionStr, xiSwfUrlStr, flashvars, params, attributes ); 

                        }
                    }
                }();
                HelloWorld.init();
            });
        </script>
        <style type="text/css">
            #flash-content-container {
                width  : 400px;
                height : 300px;
            }
        </style>
    </head>
    <body>
        <div id="layout">
            <div id="header"><h1>Hello World</h1></div>
            <div id="flash-content-container">
                <div id="flash-content"></div>
            </div>
        </div>
    </body>

I tested it on Flex 4.1, please notice that i had to add the bin-debug folder (C:\flexworkspaces\project\bin-debug) to the flash security app ( http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.htmlconfiguration ) Please notice that this internet URL is in fact an app that modifies the Flex local configuration.

The logs can be displayed in the Firebug console.




回答2:


Decided to go with FABridge. For others heres a working example.

MXML

<?xml version="1.0" encoding="utf-8"?>
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:bridge="bridge.*"
    creationComplete="init()">
    <fx:Declarations>
        <bridge:FABridge bridgeName="flex" />
    </fx:Declarations> 
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import flash.external.ExternalInterface;
            private function init():void {
                consoleLog("Hello World");
            }
            public function sendAlert(s:String):void
            {
                Alert.show(s);
            }
            public function consoleLog(message:String):void {
                if (ExternalInterface.available) {
                    ExternalInterface.call(
                        "function log(msg){ if (window.console) { console.log(msg); } }", 
                        message);
                }
            }
        ]]>
    </fx:Script>
    <s:Panel id="panel1" title="Hello World" x="20" y="20">
        <s:layout>
            <s:HorizontalLayout 
                paddingLeft="10"
                paddingRight="10"
                paddingTop="10"
                paddingBottom="10"
                gap="5" />
        </s:layout>
        <s:TextArea id="textarea1" 
            width="300" height="100" 
            text="Hello World" />       
    </s:Panel>
</s:Application>

HTML

<!DOCTYPE HTML>
<html lang="en-US">
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
        <script type="text/javascript" src="bridge/FABridge.js"></script>
        <script type="text/javascript">
            var flexApp;
            var initCallback = function() {  
                flexApp = FABridge.flex.root();  
                var textarea1 = flexApp.getTextarea1();
                textarea1.setText( "Hello World (Updated)" );
                flexApp.sendAlert( "Hello World" );
                return;
            } 
            $(function(){
                HelloWorld = function(){
                    return {
                        init : function() {
                            var swfVersionStr        = "10.1.0";
                            var xiSwfUrlStr          = "playerProductInstall.swf";
                            var flashvars            = {
                                bridgeName : "flex",
                            };
                            var params               = {};
                            var attributes           = {};
                            params.allowscriptaccess = "sameDomain";
                            params.quality           = "high";
                            params.bgcolor           = "#FFFFFF";
                            params.allowfullscreen   = "true";
                            attributes.id            = "HelloWorld";
                            attributes.name          = "HelloWorld";
                            attributes.align         = "left";
                            swfobject.embedSWF( 
                                "HelloWorld.swf", 
                                "flash-content", 
                                "100%", "100%", 
                                swfVersionStr, xiSwfUrlStr, flashvars, params, attributes ); 
                            FABridge.addInitializationCallback( "flex", initCallback );
                        }
                    }
                }();
                HelloWorld.init();
            });
        </script>
        <style type="text/css">
            #flash-content-container {
                width  : 400px;
                height : 300px;
            }
        </style>
    </head>
    <body>
        <div id="layout">
            <div id="header"><h1>Hello World</h1></div>
            <div id="flash-content-container">
                <div id="flash-content"></div>
            </div>
        </div>
    </body>
</html>


来源:https://stackoverflow.com/questions/7519112/call-an-adobe-flex-actionscript-method-from-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!