Space of Flex/AIR technologies

Beyond Plain Old Html Objects

Archive for the ‘AIR’ tag

Flerry 1.1.1 released supporting large objects transfer

with one comment

I just released a new version of Flerry that fixes a problem with transferring large object structures from Java to Flex. This release is thanks to Mohammed Abbas who contributed the patch. Again I’m really happy that this project is evolving and the community is contributing to it actively.

To start working with Flerry go ahead and download the flerry and flerry-demo projects. You may also find my previous posts (Post 1 | Post 2) helpful.

Written by Piotr Walczyszyn

July 5th, 2010 at 3:00 pm

Posted in Releases

Tagged with , ,

Flerry 1.1.0 released with a two-way Flex-Java communication

with 7 comments

I would like to proudly announce that Flerry 1.1.0 was released! For those of you that don’t know what is Flerry, it’s a Flex-Java bridge for Adobe AIR 2.0. This new release brings possibility to call/initiate communication from Java to Flex/AS3 code. This functionality was solely developed by Jhonny Everson, big kudos to Jhonny!!! I love when open source really works and community contributes their work, with that said I encourage any of you that use Flerry to commit to the project ;)

You can grab latest FB4 project with Flerry and demo app from here.

Usage is really simple:

First create instance of NativeObject either in MXML or AS3 (binPath is path to jar file with compiled Java source classes):

<flerry:NativeObject id="nativeObject" singleton="true" 
binPath="./jars/flerry-demo.jar"  source="net.riaspace.flerrydemo.MyJavaObject" />

Next subscribe to messages sent from Java side, “sendMsg” parameter defines message identifier:

// Subscribe to receive remote messages.
nativeObject.subscribe("sendMsg", messageHandler);

On the Java side you have static method sendMessage on NativeObject class with message parameter and again message identifier:

NativeObject.sendMessage(map, "sendMsg");

Written by Piotr Walczyszyn

June 30th, 2010 at 10:30 am

Posted in Releases

Tagged with , ,

Multi-touch development with Flash and Flex e-seminar materials

with 2 comments

Below you will find links to my e-seminar recording, presentation slides and projects with source code of demo applications:

Written by Piotr Walczyszyn

March 17th, 2010 at 9:39 pm

Posted in Uncategorized

Tagged with , , ,

Real-Time Mobile Connectivity

with 12 comments

In the video below I present my new demo of real-time connectivity between applications running on different devices like Apple phone, Nexus One and my Mac. Apple phone runs AIR application built with Flash (source code available here), on the desktop is also an AIR app but built with Flex (source code available here) and on Nexus One is also Flex app (keep in mind that this is not yet Flex Mobile version, source code available here) running in the browser. All of these connect through Java backend with LiveCycle Data Services ES2 (source code available here).

Written by Piotr Walczyszyn

March 16th, 2010 at 9:09 am

Posted in Uncategorized

Tagged with , ,

Multitouch development with Flash and Flex (e-seminar this Wednesday)

with one comment

This Wednesday (17.03.2010, 11:00am CET) I will be doing an online e-seminar about “Multitouch development with Flash and Flex”. You will learn how you can start immediately building multitouch enabled applications, what new APIs are coming with FP10.1 and AIR 2.0, what the differences are, and what is supported on underlying operating systems. Please register here: http://multitouchflex.eventbrite.com

This will be 30-minute session followed by a 15-minute Q&A part, done via Adobe Connect room: http://my.adobe.acrobat.com/multitouchflex/

Written by Piotr Walczyszyn

March 15th, 2010 at 12:03 pm

Posted in Events

Tagged with , ,

Adobe AIR 2.0 Beta 2 released!

with 5 comments

Adobe AIR 2.0 Beta 2 was just released; it is available here on Adobe Labs!

New features:

  • Enhanced Printer Interaction: New printing support allows finer control of the way content is printed from an AIR application, including the choice of printer, paper size, and number of copies. New APIs allow a developer to retrieve additional printing information, such as printable area, whether the printer will print in color, and whether the print job is currently active. It is also possible to print without displaying the print dialog.
  • Support for TLS/SSL socket communication: You can now connect to a server that requires TLSv1 or SSLv3 for socket communications.
  • IME API and IME Text Input Enhancement: There are several new features added in this release to support better text input handling with IME software. The new API enhancements are designed for use with the new Flash Text Engine (FTE).

You can find updated sample applications here.

IMPORTANT: Applications built against Adobe AIR 2 Beta 1 will not run using the AIR 2 beta 2 runtime. In order for an AIR 2 Beta 1 application to run on the AIR 2 Beta 2 runtime, the namespace of the Beta 1 application descriptor file must first be updated to “2.0beta2″ and the application must be recompiled using the AIR 2 Beta 2 SDK.

Written by Piotr Walczyszyn

February 2nd, 2010 at 6:31 pm

Posted in News,Releases

Tagged with

Java-AS3 serialization with AMF

with 5 comments

A few weeks ago I published Flerry project a Flex-Java bridge for AIR 2.0. In this post I wanted to explain how it works and what I used on the Java side to do AS3/Java AMF de/serialization. First of all Flerry uses the new NativeProcess API that comes with AIR 2.0. This new API allows communication between AIR application and any native application running on a user’s machine with standard input, output or error streams. Almost any type of data can be transferred over those streams, ranging from simple strings, numbers, Booleans, bytes and byte arrays to AMF serialized AS3 objects. Of course if AMF serialized AS3 objects are streamed then receiving side of the communication needs to understand this format. In the case of Flerry, the receiving side is Java and obviously it doesn’t have a built-in AMF deserializer. In order to enable AMF on the Java side I decided to investigate Adobe’s Open Source BlazeDS project (BlazeDS is the server-based Java remoting and web messaging technology that enables developers to easily connect to back-end distributed data and push data in real-time to Adobe® Flex® and Adobe AIR™ applications for more responsive rich Internet application (RIA) experiences). As BlazeDS is designed to work by default inside of JEE containers it must have had it already implemented.

After a short investigation it turned out that I was right and BlazeDS comes with very simple to use AMF de/serializer. What you actually need to make it work are two jar files: flex-messaging-common.jar and flex-messaging-core.jar, which are in the BlazeDS package available for download from here. In those jars I found two classes Amf3Input and Am3Output that allowed me to send and receive AMF serialized AS3/Java objects over input/output/error streams.

So how does it all work?

On the AS3 side I used the NativeProcess.standardInput.writeObject(message) function where the message object is of the type flex.messaging.messages.RemotingMessage that maps to equivalent flex.messaging.messages.RemotingMessage on the Java side with the proper RemoteClass metadata. Of course any POAO (Plain Old ActionScript Object) could be used instead of RemotingMessage. In my case I just wanted to reuse standard classes out of the Flex SDK that wrap transferred content and add properties required for asynchronous communication.

Below is actual code from Flerry that writes AMF serialized AS3 objects to the standard input stream (source code of NativeObject.as class is available here):

protected function call(method:NativeMethod, ... args):AsyncToken
{
	if (!nativeProcess)
		initialize();
 
	var message:RemotingMessage = new RemotingMessage();
	message.operation = method.name;
	message.source = source;
	message.headers = {SINGLETON_HEADER:singleton};
 
	if (args.length == 1)
		message.body = args[0];
 
	nativeProcess.standardInput.writeObject(message);
 
	var token:AsyncToken = new AsyncToken(message);
	tokens[message.messageId] = token;
 
	return token;
}

On the Java side I used the Amf3Input class to deserialize received data from the input stream (System.in) into proper Java objects (source code of NativeObject.java class is available here):

public void init()
{
	Amf3Input amf3Input = new Amf3Input(SerializationContext.getSerializationContext());
	amf3Input.setInputStream(System.in);
	try
	{
		Object object;
		while ((object = amf3Input.readObject()) != null)
		{
			if (object instanceof RemotingMessage)
			{
				RemotingMessage message = (RemotingMessage) object;
				try
				{
					if (message.getSource() != null)
					{
						Object sourceObject = null;
						if (singleton)
							sourceObject = singletonObject;
						if (sourceObject == null)
						{
							sourceObject = sourceClass.newInstance();
							if (singleton)
								singletonObject = sourceObject;
						}
 
						Object[] params = (Object[]) message.getBody();
						Class[] paramsTypes = new Class[params.length];
						for (int i = 0; i &lt; paramsTypes.length; i++)
						{
							paramsTypes[i] = params[i].getClass();
						}
 
						Object result = sourceObject.getClass().getMethod(message.getOperation(), paramsTypes).invoke(sourceObject, params);
						respond(result, message.getMessageId());
					}
					else
					{
						Boolean stopProcess = (Boolean) message.getHeader(NativeObject.STOP_PROCESS_HEADER);
						if (stopProcess != null &amp;&amp; stopProcess)
						{
							break;
						}
					}
				}
				catch(Exception e)
				{
					handleException(e, message.getMessageId());
				}
			}
			else
			{
				handleException(new Exception(
						"Received object is not RemotingMessage type!"), null);
			}
		}
	}
	catch (Exception e)
	{
		handleException(e, null);
	}
	finally
	{
		try
		{
			amf3Input.close();
		}
		catch (IOException e)
		{
			handleException(e, null);
		}
	}
}

To send data back to AIR I used the Amf3Output class. With a little help from ByteArrayOutputStream Java objects are serialized to AMF format and written back to System.out.

protected void respond(Object object, String correlationId)
{
	try
	{
		Amf3Output amf3Output = new Amf3Output(SerializationContext.getSerializationContext());
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		amf3Output.setOutputStream(baos);
 
		AcknowledgeMessage message = new AcknowledgeMessage();
		message.setBody(object);
 
		message.setCorrelationId(correlationId);
		amf3Output.writeObject(message);
		System.out.write(baos.toByteArray());
 
		amf3Output.close();
	}
	catch (Exception e)
	{
		handleException(e, correlationId);
	}
}

Written by Piotr Walczyszyn

February 1st, 2010 at 5:11 pm

Posted in Examples

Tagged with , ,

File promises with Adobe AIR 2.0

with one comment

File promises is one of the new AIR 2.0 features already available in beta on Adobe Labs. “A file promise is a drag-and-drop clipboard format that allows a user to drag a file that does not yet exist out of an AIR application. AIR uses the methods and properties defined by the IFilePromise interface to access the data to be written when the file promise is dropped.” To check out how it works, I built a sample application that allows you drag an AIR icon out of the app and drop it somewhere in your system (e.g. on your desktop). Dropping it will initiate a download of the current stable AIR runtime installer (at this point in time it is AIR 1.5.3). The downloaded file containing the runtime will be appropriate for your operating system. This logic is implemented in the fileUrl function and it uses the Capablities.os property with a simple regexp search for “win”, “lin”, or “mac” patterns.

Here is how the application looks:

Below is the source code:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication 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:halo="library://ns.adobe.com/flex/halo"
					   currentState="START_STATE" height="200" width="300" viewSourceURL="srcview/index.html">
 
	<s:layout>
		<s:VerticalLayout horizontalAlign="center" gap="15"/>
	</s:layout>
 
	<fx:Script>
		<![CDATA[
			import flash.events.Event;
			import flash.events.MouseEvent;
			import flash.system.Capabilities;
 
			protected var filePromise:URLFilePromise;
 
			protected function imgAirIcon_mouseDownHandler(event:MouseEvent):void
			{
				// Instantiating new file promise
				filePromise = new URLFilePromise();
				// Registering OPEN event listener, to switch to 
				// DOWNLOAD_STATE when downloading starts
				filePromise.addEventListener(Event.OPEN, onOpen);
 
				// Setting URLRequest pointing to remote file
				filePromise.request = new URLRequest(fileUrl);
				// Setting relativePath with fileName to be saved locally
				filePromise.relativePath = fileName;
 
				// Array of promises with single promise in this case
				var promises:Array = new Array();
				promises.push(filePromise);
 
				// Instantiating clipboard object pointing to the promise
				var clipboard:Clipboard = new Clipboard();
				clipboard.setData(ClipboardFormats.FILE_PROMISE_LIST_FORMAT, promises);
 
				// Dragging with NativeDragManager
				NativeDragManager.doDrag(imgAirIcon, clipboard);
			}
 
			protected function onOpen(event:Event):void
			{
				currentState = "DOWNLOAD_STATE";
				prgBar.source = filePromise;
			}
 
			protected function get fileUrl():String
			{
				// Returns remote file URL based on current operating system
				if (Capabilities.os.search(/mac/i) > -1)
					return "http://airdownload.adobe.com/air/mac/download/latest/AdobeAIR.dmg";
				else if (Capabilities.os.search(/win/i) > -1)
					return "http://airdownload.adobe.com/air/win/download/latest/AdobeAIRInstaller.exe";
				else 
					return "http://airdownload.adobe.com/air/lin/download/latest/AdobeAIRInstaller.bin";
			}
 
			protected function get fileName():String
			{
				var fileUrl:String = fileUrl;
				return fileUrl.slice(fileUrl.lastIndexOf("/") + 1);
			}
		]]>
	</fx:Script>
 
	<s:states>
		<s:State name="START_STATE"/>
		<s:State name="DOWNLOAD_STATE"/>
	</s:states>
 
	<halo:Image id="imgAirIcon" source="assets/air_icon_special.gif" mouseDown="imgAirIcon_mouseDownHandler(event)" toolTip="{fileUrl}" />
 
	<s:Label text="(Drag it out to start download)" />
 
	<halo:ProgressBar id="prgBar" bottom="10" horizontalCenter="0"  visible="false" visible.DOWNLOAD_STATE="true" label="Downloading {int(prgBar.percentComplete)}%"/>
 
</s:WindowedApplication>

Written by Piotr Walczyszyn

January 26th, 2010 at 5:37 pm

Posted in Examples

Tagged with

Flerry: Flex-Java bridge for Adobe AIR 2.0

with 81 comments

Today I published Flerry on Google Code, a Flex-Java bridge that uses NativeProcess API from Adobe AIR 2.0. Using it is very simple and similar to RemoteObject API in Flex. In fact I reused libraries from BlazeDS to do AMF de/serialization on Java side and on Flex side classes like AsyncToken, RemotingMessage, AcknowledgeMessage and ResultEvent/FaultEvent for eventing.

Here is short snippet how you can use it directly in MXML:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="300" minHeight="200" xmlns:flerry="net.riaspace.flerry.*">
    <fx:Script>
        <![CDATA[
            import flash.events.MouseEvent;
 
            import mx.controls.Alert;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;
 
            protected function nativeObject_faultHandler(event:FaultEvent):void
            {
              Alert.show(event.message.toString());
            }
 
            protected function addMethod_resultHandler(event:ResultEvent):void
            {
              txtResult.text = event.result.toString();
            }
 
            protected function btnAdd_clickHandler(event:MouseEvent):void
            {
              nativeObject.add(parseInt(txtValue1.text), parseInt(txtValue2.text));
            }
            ]]>
    </fx:Script>
    <fx:Declarations>
 
    <!-- Declaring NativeObject that points to 
            net.riaspace.flerrydemo.MyJavaObject class in ./jars/flerry-demo.jar -->
    <flerry:NativeObject id="nativeObject" binPath="./jars/flerry-demo.jar" 
            source="net.riaspace.flerrydemo.MyJavaObject"
            fault="nativeObject_faultHandler(event)">
 
      <!-- Declaring NativeMethod with custom result handler, for this example 
              actually result from NativeObject could be used -->
      <flerry:NativeMethod id="addMethod" name="add" 
            result="addMethod_resultHandler(event)" />
 
    </flerry:NativeObject> 
 
  </fx:Declarations>
 
  <s:HGroup verticalAlign="middle" textAlign="center" horizontalCenter="0" verticalCenter="0">
    <s:TextInput id="txtValue1" text="2" width="30" />
    <s:Label text="+" width="30" />
    <s:TextInput id="txtValue2" text="3" width="30" />
    <s:Button id="btnAdd" label="=" width="30" click="btnAdd_clickHandler(event)" />
    <s:TextInput id="txtResult" width="30" editable="false" />
  </s:HGroup>
 
</s:WindowedApplication>

Some NativeObject properties:

  • binPath – points to jar file with your Java application
  • source – points to java class that this NativeObject maps to
  • singleton – sets source class object as singleton
  • startupInfoProvider – custom implementation of net.riaspace.flerry.IStartupInfoProvider, by default Flerry comes with JavaStartupInfoProvider that tries to detect where Java is installed on users machine, in other case Error is thrown

In following posts I will explain in details how it all works, for now you can download flerry Flash Builder project with all the source code from here.

Written by Piotr Walczyszyn

January 13th, 2010 at 7:32 pm

Posted in Examples,Releases

Tagged with , ,

ipla lite: Adobe AIR based client of video content from Polsat group

with 4 comments

ipla-logoipla lite application was recently released, this is an Adobe AIR/Flex based client of video content published by Polsat group. Polsat is one of the biggest TV stations in Poland. This release is really great news for Mac and Linux users because ipla’s original version released in 2008 was only available for Windows platforms. In this case Adobe AIR brings outstanding capabilities like: video, audio and cross-platform support. At the moment this release allows watching live streaming content, prerecorded TV shows in VOD mode, do video search and navigate through video categories. I know there are other plans to extend it with features known from full Windows version like social networking. Personally I would also like to see capabilities like local video caching (for offline mode watching), Twitter integration, video deeplinking (maybe something similar as we recently introduced for the content from Adobe MAX) – time will show ;)

Here are some screens with application UI:

Written by Piotr Walczyszyn

October 19th, 2009 at 4:24 pm

Posted in Releases

Tagged with ,

Switch to our mobile site