So I have an Application Sandbox HTMLLoader object which I create in AIR and simply want to call ActionScript methods from JavaScript. In Flash, this is accomplished through our trusty ExternalInterface.addCallback() function. However in AIR, things are quite a bit different, and I just can’t seem to get it to work.
Here is a simplified overview of my project:
My AIR (ActionScript) main:
public class Main extends Sprite { public var _as3Var:String = 'testing'; public function as3Function():void { trace('as3Function called from Javascript'); } public function Main() { NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvoke); } protected function onInvoke(e:InvokeEvent):void { NativeApplication.nativeApplication.removeEventListener(InvokeEvent.INVOKE, onInvoke ); var app = new App(); addChild(app); app.init(new ExternalContainer(), e.currentDirectory, e.arguments); } }
And this is how I create my HTMLLoader object:
{ _html = new HTMLLoader(); _html.useCache = false; _html.runtimeApplicationDomain = ApplicationDomain.currentDomain; _html.load(new URLRequest('sandbox/AirRoot.html')); _html.width = 800; _html.height = 600; App.ref.addChild(_html); }
And at last, here is my snippet of JavaScript in my AirRoot.html file which is trying to call the public method as3Function() declared in my Main class:
Exposed.testAs3 = function() { air.trace('Exposed.testAs3 called'); /* This works fine. */ air.trace('runtimeVersion:'); /* This works fine. */ air.trace(air.NativeApplication.nativeApplication.runtimeVersion); /* This works fine. */ air.trace('seeing if I can get to AS3 params...'); /* This works fine. */ /* This doesn't work - get the following error: TypeError: Value undefined does not allow function calls. */ air.NativeApplication.nativeApplication.as3Function(); }
What am I missing?
OK, I am going to answer my own question. I promise this was not a ploy to gain more reputation points, but I was seriously confused today but have now found the appropriate answers and documentation – which is usually the main problem to many an engineer’s question…
Anyway, the answer:
The AIR HTMLLoader object contains a magical property,
HTMLLoader.window, which is a proxy to the JavaScript window object. So settingHTMLLoader.window = AS3Function;is one way – or in relation to my previously included example (assuming I setup a static property called Main which pointed to the Main class):And now in JavaScript I can just call
as3Functionas:Another interesting property is the JavaScript ‘window.htmlLoader’ object. It is a proxy to the AS3 HTMLLoader parent object, in my case, the _html object. From this you can access things in relation to the _html object from JavaScript.