Flex Mobile: Invoking JavaScript in a StageWebView

The StageWebView allows you to render HTML content inside a Flex application using the underlying HTML rendering engine available on your mobile device.

In some situations, the Flex application may need to communicate with the HTML document hosted in the StageWebWiew. In other words, you may need to invoke a JavaScript function available in that document from the Flex application.

The basic approach is to use the StageWebView loadURL() function with the javascript: protocol as follows:

stageWebView.loadURL("javascript:myFunction()");

For example, if you need to invoke the addItem() function providing the firstName and lastName values captured in the Flex application, you’d do something like this:

stageWebView.loadURL("javascript:addItem('" +
        firstName.text + "', '" + lastName.text + "')");

iOS Technique

On iOS however, you can’t currently use the javascript: protocol to invoke a function using loadURL() as described above. What you can do is use the javascript: protocol to change the location of the document. So the trick is to just change the hashtag at the end of the URL as a “signal” to tell the page you want to execute an action (if the base URL doesn’t change, the page is not reloaded). You can come up with your own hashtag format convention to specify the method to invoke and parameters to pass. In this case, since I only have one method to invoke, I just use the hashtag to pass the values (first name and last name).

counter++;
webView.loadURL("javascript:window.location='http://foo.com/bar.html" +
        "#" + firstName.text +
        "&" + lastName.text +
        "&" + counter + "'");

NOTE: The incremented counter is used to ensure that the hashtag is changing on consecutive method invocations even if the first name and last name are the same (otherwise the onhashtag event would not fire).

In the HTML page, we use the onhashchange event to listen for hashtag changes and then trigger the appropriate action. My JavaScript looks as follows:

function addItem(firstName, lastName) {
	var list = document.getElementById('list');
	var li = document.createElement('li');
	li.appendChild(document.createTextNode(firstName + " " + lastName));
	list.appendChild(li);
}

window.onhashchange = function() {
	var newHash = window.location.hash.substring(1);
	var a = newHash.split("&");
	addItem(a[0], a[1]);
};

Final Note

The Flash Builder simulator does not support the onhashchange event. So to test my application in the simulator (and to use the default approach when not on iOS), I use the following code:

if (Capabilities.os.indexOf("iPhone OS") == -1)
{
	webView.loadURL("javascript:addItem('" +
		firstName.text + "', '" + lastName.text + "')");
}
else
{
	counter++;
	webView.loadURL("javascript:window.location='" + url +
		"#" + firstName.text +
		"&" + lastName.text +
		"&" + counter + "'");
}

You can download the Flex project here: http://coenraets.org/webview/StageWebViewJavaScriptDemo.fxp

The HTML and JavaScript files are here:

Comments

  1. Ben Clinkinbeard says:

    I’ve been using the javascript:someFunction() syntax on iOS without issue.

  2. Ganesh says:

    my flash builder 4.5 does not show option for mobile platform for ios and blackberry it just show option for android
    current i am using flash builder 4.5
    flex sdk updates to 4.5.1
    stiill its not working
    check inage on=http://forums.adobe.com/thread/883052

  3. When passing parameters like that in a string, you also escape special characters.
    If someone’s name contains a quote (‘) character, this will break.

    In this example that is a relatively harmless bug. If your parameters come from an untrusted source, then you have created a cross-site-scripting vulnerability.

  4. amlan says:

    Thanks for the great example but can you show a demo of how to do the same thing with a local javascript/html file( containing the javascript) file (in the assets folder of the project).

    Thanks in advance

  5. HAve you experienced any problems when you execute 2 (or more) after each other in iOS? Cause when I’m doing this the javascript is call twice, but the parameters have the value of the parameters you passed a long with the last method call.

    So for example:
    first call:
    firstname: Maikel
    lastname: Sibbald

    second call:
    firstname: Christophe
    lastname: Coenraets

    I receive in the javascript twice Christophe Coenraets.
    It’s working for me when I setTimeout of 2 sec. But that’s not a option for me.. isn’t there some event or call back option to tell actionscript its ready for another call..

    thanks,

    Maik

    btw. good article!

  6. Apinan says:

    The call can be made but anybody knows how can we get the return value from javascript function?
    Thanks

  7. Xperiments says:

    Hi, you can use the stagewebviewbridge class to do this sort of communication. http://code.google.com/p/stagewebviewbridge/

    by nos the only problem is that it don’t work in android, but i am finishing the modifications to do it …

  8. Mamta says:

    I am using stageWebView for showing webpage in my mobile app but don’t know how to move back to my app once it gets loaded. In application descriptor file, I had already registered custom uri scheme (myapp://) for IOS devices and from the loaded page inside stageWebView, I was trying to call following URL myapp://webcam. But nothing had happened. It neither called LOCATION_CHANGE event of StageWebView not called INVOKE_EVENT of nativeapplication.

    How can I fix this issue?

    Thanks in advance,
    Mamta

  9. Thanks, this blog is very good!!

  10. xperiments says:

    Hi,

    I have update the StageWebViewBridge class to work with android and some other improvements…

    http://code.google.com/p/stagewebviewbridge/

    StageWebViewBridge is an extended version of flash.media.StageWebView.

    Extends Bitmap class, you can modify his x,y,alpha,rotation,visible, etc ( Version 1 Beta )
    Communicates Actionscript with Javascript.
    Communicates Javascript with Actionscript.
    Load local files and resources in a easy way.
    Extends loadString method with AS3 – JS communication.
    Extends loadString method to load local resources.
    Lets you take an SnapShot to use as the bitmapData of the bitmap.

  11. sunil says:

    I am trying to run Flex mobile app using StageWebView in android emulator. I have installed AIR3.0 and FlashPlayer 10.1 in the emulator. When i run the apk, android emulator asks for FlashPlayer to be installed. Why is it so when the Flash Player is already available? Any clues..

Trackbacks

  1. [...] JQuery in a Flex Application This is a follow up to my previous post on how to invoke a JavaScript function in an HTML document hosted in a Flex application (using the [...]

  2. [...] is a follow up to my previous post on how to invoke a JavaScript function in an HTML document hosted in a Flex application (using the [...]

Speak Your Mind

*