Adobe Flex/AIR developers rejoice - AIR 2.0 (code name Athena) is coming, and it contains many highly requested features that application developers have been waiting on since AIR 1.0 was released nearly two years ago. If you have AIR 1.x applications in the wild, I suggest you download the AIR 2.0 SDK beta and test your application(s) now. When Adobe releases the new runtime, it will be automatically downloaded and installed by all of your users. It's important to test now to make sure you're not caught off guard. And, you can get a great headstart using some of the new features.
In February of 2008, Adobe released AIR 1.0, which provided developers the ability to create Rich Internet Applications that execute outside of the confines of the browser. AIR applications are multi-platform (Mac, Windows and Linux) desktop applications that are written in ActionScript 3 and/or HTML/Javascript/CSS.
Since its initial release, there have been minor language enhancements and bug fixes. Many developers were disappointed at the absence of some important features as well as the poor runtime performance and high resource requirements of even the simplest of applications. Despite that, AIR has brought the power of Flex and the RIA to the desktop and added a significant piece to the Adobe Flash Platform. The stated theme of the AIR 2.0 release is tighter integration with the desktop.
According to information found on the Adobe Labs site, where you'll be able to download the beta 1 version, AIR 2.0 is expected to be released sometime in the second quarter of 2010. Keep in mind that it is still beta 1, so things can change. Features can be withdrawn, added and changed.
The list of the most notable new features available in AIR 2.0 include:
- Native code integration
- Global exception handling
- Improved networking support with server sockets, secure sockets, UDP and IPV6
- Updated version of WebKit including support for HTML5 and CSS3
- Improved runtime performance and lower resource requirements via Flash Player 10.1
- Multi-touch and gesture support
- Tighter integration with the desktop including automatic detection of mass storage devices, improvements to cross-platform printing, opening files with their default application and a new set of language API's for accessing and processing audio streams from the microphone
- Screen reader support (Windows only) for creating accessible applications
- Improved database support with transaction savepoints
- File Promises (explained later)
Native Code Integration
This is probably the most requested feature in all of AIR 2.0 and many developers were disappointed by the fact that it was missing from AIR 1.0. Take heart, it's now available.
This feature allows an AIR application to start and interact with a native process. That means you can now launch native applications that are installed on your user's desktops and/or native applications that you distribute with your AIR application.
In order to have access to native processes, a native application installer must have been used to install your application instead of the application installer built into the Adobe AIR runtime.
There are some drawbacks to this in that you must now compile and create platform-specific distributions of your application. Further, these distributions must be created on the platform for which they are intended. In other words, you must create a native Windows installer (.exe file) from a Windows machine, a native Mac installer (.dmg file) from a Mac machine and a native Linux installer (.deb/.rpm package) from a Linux machine.
This complicates the process of creating distributable versions of your application. ADT is used to generate your installer(s) and you can either build them from an existing AIR/AIRI file or directly from the source files and application descriptor.
No tooling support yet exists in FlashBuilder to generate native installers, but that will certainly exist when FlashBuilder is released. For reference, FlashBuilder 4 is the latest version of the Flex/AIR authoring tool from Adobe (previously known as FlexBuilder). FlashBuilder 4 is also still in beta.
There are three new classes in AIR 2.0 that you will use when launching and interacting with native processes.
The new flash.desktop.NativeProcess
class allows you to launch, interact with and terminate a process. Programmatic interaction is optional. You may simply launch a process and add an event listener to the process to be notified when the user exits or you may launch it, interact with it and terminate it through the API.
All interaction with native processes is done through standard input, standard error and standard output and is asynchronous. If you wish to interact with it, it must be written to read from standard output and write to standard input. You cannot arbitrarily choose a native application and expect to be able to interact with it unless it is specifically written to do so.
Regardless, you can use the NativeProcess API to launch the browser, an e-mail client, an office productivity application, or any other process, let the user interact with it and when the user exits that application, your AIR application can be notified.
The very simple flash.desktop.NativeProcessStartupInfo
class contains only information about the process you intend to launch. It allows you to specify which File represents the executable as well as any arguments that are passed to the process when it is launched. An instance of this class is passed as an argument to the NativeProcess.start() function.
The flash.events.NativeProcessExitEvent
class is a standard Flash Event subclass that is dispatched by the native process when it exits. In order for your application to be notified when a native process exits, you must add an event listener to the process itself. Through this event, you have access to the exit code so you can take appropriate action and determine whether the process terminated normally or not.
Global Exception Handling
This feature is not specific to AIR 2.0 and is instead part of an update to the underlying Flash Player upon which the AIR runtime is built. So, the ability to handle uncaught exceptions will be possible in Flash, Flex and AIR so long as you're running against Flash Player 10.1 or greater. I'll cover the Flash Player 10.1 update a bit later in the article.
The absence of a global exception handler in the Flash Platform has been puzzling at best, especially when you consider what happens to your users at runtime when an uncaught exception occurs in your applications and how difficult it can be to diagnose.
Prior to AIR 2.0, when a user of your application encounters an uncaught exception, there is absolutely no indication anywhere that an exception has occurred. The user is not notified in any way and your code has no opportunity to be notified. What you often get are reports from your users that your application is behaving very strangely and neither you nor the user has an easy way to determine why. Of course, if your user is running the debug version of the Flash Player, then a very unfriendly error dialog showing a very unfriendly error message and stack trace will appear. But, most users aren't running the debug player and in the case of AIR applications, they won't be anyway.
In languages like Java, there are well known entry points into a process. The static main method is used for standalone applications and the service method for servlets. You can easily wrap your code in a try/catch block and no matter what happens deep inside the application, that method remains atop the stack. An uncaught exception will bubble up and be caught. That means you can know when an exception has occurred, where it occurred (via the stacktrace) and take action such as logging the exception for future diagnosis and/or returning a friendly error message to your user.
On the Flash Platform, there is no such well known entry point. Therefore, there is no logical place that a developer can put a single try/catch block to handle an uncaught exception. Even if there was, the asynchronous nature of the Flash Platform makes a simple solution impossible, until AIR 2.0...well almost.
In AIR 2.0, you can now declare a global exception handler that will be invoked no matter where or when an uncaught exception occurs. This is accomplished in your WindowedApplication
applicationComplete event handler by executing the following code.
loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtError);
While this is a huge step forward for ActionScript developers, Adobe has said that stack traces for uncaught exceptions will not be available at runtime (except when running the debug player). That means that your code will handle exceptions, log them and/or display notifications to the user, but finding out where in your code that the exception occurred is going to be challenging at best without stack traces.
Improved Networking Support
AIR 2.0 brings several key networking enhancements including server sockets, secure sockets, UDP and IPv6.
Server Sockets
The new flash.net.ServerSocket
class provides the ability for an AIR application to act as a server and listen for incoming TCP socket requests. Prior to AIR 2.0, an AIR application could only connect over TCP as a client. Both IPv4 and IPv6 are supported.
By adding an event listener to the server socket, the flash.events.ServerSocketConnectEvent
class allows your code to be notified when a connection to the server socket has been made and you can then communicate with the client over the resulting socket.
Secure Sockets
The new flash.net.SecureSocket
class is a flash.net.Socket
subclass and provides the ability to connect to a trusted server using SSL and TLS to enable encrypted communication. The underlying operating system mechanism for determining the validity and trust of a certificate. The socket will only connect if the underlying OS verifies that there are no problems with the certificate or the certificate chain.
Prior to AIR 2.0, external libraries such as the as3crypto library were used to provide secure socket communications. The SecureSocket
class provides support for SSLv3 and TLSv1.
UDP
The new flash.net.DatagramSocket
class provides the ability to connect to other hosts using the UDP internet protocol. Compared to TCP socket connections provided by the flash.net.Socket
and its subclasses, UDP connections send messages, known as datagrams. UDP is considered an unreliable service and does not guarantee that the packets sent will arrive in order or arrive at all. UDP forgoes the protocol requirements of ensuring delivery, retransmitting packets that were lost, duplicated or fragmented in favor of simplicity and speed and is ideal when the overhead, service levels and increased network latency of the TCP protocol are unnecessary.
IPv6
All network classes that utilize internet addresses now support both IPv4 and IPv6. This includes Socket
, DatagramSocket
and SecureSocket
.
Other Networking enhancements
There are a two other sets of classes that provide additional networking support.
The new flash.net.dns.DNSResolver
class allows your application to interrogate Domain Name System (DNS) resource records. The DNSResolver
class allows you to lookup records of the following type for a specific IP address or hostname:
- ARecord – IPv4 address for a specific host
- AAAARecord – IPv6 address for a specific host
- MXRecord – Mail exchange record for a specific host
- PTRRecord – Host name for an IP address
- SRVRecord – Service record for a service
The flash.net.NetworkInfo
class provides the ability to discover information about the network interfaces present on your computer such as wired and wireless interfaces. This class can provide a list of flash.net.NetworkInterface
instances that exist on the machine. Your application can add an event listener to the NetworkInfo
and be notified when the network changes in some way such as when your computer joins or disconnects from a wired or wireless network or a VPN.
The NetworkInterface
class provides access to information about each including its display name, the hardware address, MTU and the name by which it is known.
Updated version of WebKit
AIR has always provided HTML support via the mx.controls.HTML
component and the integrated WebKit web browser engine. Adobe has always had support to allow developers to write applications in HTML, Javascript and CSS and access the AIR API. AIR 2.0 brings in the equivalent of the Safari 4.03 WebKit branch, which includes the following new features:
- Support for HTML 5 including the new Canvas tag
- A new Javascript engine (SquirrelFish Extreme) resulting in significant performance increases
- New CSS3 features including CSS Transitions, Animations and Gradients
- Support for –webkit CSS selectors
- Support for CSS Zoom to control magnification of an HTML element
Improved performance via Flash Player 10.1 update
The Adobe AIR 2.0 runtime is now based upon the Flash Player (FP) 10.1 update. According to Adobe, FP 10.1 "realizes the promise of a consistent, cross-platform runtime across desktop and mobile devices". A wide range of mobile devices are supported including smartphones, netbooks and others.
FP 10.1 adds all sorts of features aimed at both the mobile and desktop platforms. Some of the enhancements benefit both platforms, though a majority of them are aimed squarely at mobile.
The mobile platform is generally constrained by devices with significantly lower capacity CPUs and available memory. In order for FP to be viable on the mobile platform, Adobe has had to focus heavily on improving performance of FP. According to Adobe, these improvements include rendering, scripting memory, start-up time, battery and CPU optimizations - all of these will be welcomed by AIR developers, who have suffered from significant resource utilization for even small applications with AIR 1.0.
For reference, the FP 10.1 update adds support for native device capabilities including multi-touch, gestures, mobile input models and accelerometer input. FP 10.1 runs on Windows (including the new Windows 7), Mac (including OS X 10.6), Android, Windows Mobile 6.5, Palm webOS and Symbian S60.
All of the features, improvements and capabilities are beyond the scope of this article. FP 10.1 is currently available as a beta from Adobe Labs where you can read all about it, download it and play with.
Multi-touch and gesture support
The mobile platform and the newer desktop operating systems including Windows 7 have changed the way we interact with our devices. This new support allows you to write AIR applications that use gestures such as pinch, scroll, rotate, scale and two-finger tap.
Several new classes have been added that provide the ability to write applications that support this new method of input assuming that the device on which the application is running supports this. AIR provides a way to programmatically determine whether the device supports this and the extent to which it is supported through the flash.ui.Multitouch
class.
Subclasses of flash.display.InteractiveObject
, which is essentially every single visual component in the Flex framework provide multi-touch and gesture support through the dispatching of various events.
Touch Events
The following multi-touch events are possible:
- touchBegin – Dispatched when the user touches a touch-enabled device
- touchEnd – Dispatched when the user lifts a finger from a touch-enabled device
- touchMove – Dispatched when the user slides a finger across a touch-enabled device
- touchOut – Dispatched when the user slides a finger away from a component
- touchOver – Dispatched when the user slides a finger over a component
- touchRollOut – Dispatched when the user slides a finger away from a component
- touchRollOver – Dispatched when the user slides a finger over a component
- touchTap – Dispatched when the user touches and then releases a finger from a single point
As a point of clarification, it appears by the description that the touchOver/touchRollOver and touchOut/touchRollOut events are identical. There is a subtle, but important distinction between the two that is essentially a difference in the actual events. The touchRollOver/touchRollOut events do not bubble, whereas the touchOver/touchOut events do bubble. This can yield slightly different visual results depending upon what your code is doing when handling these events.
Lets assume that you have a VBox container with five child buttons. You wish to change the background color of the VBox from white to red when you move over the VBox or any of its children and from red to white when you move out of the VBox. To implement this sort of behavior, you may choose to listen for either the touchRollOver/touchRollOut or the touchOver/touchOut on the VBox.
If you choose to listen for the touchOver/touchOut events, the VBox itself will dispatch a touchOver event when you move over the VBox. When you move over one of the children buttons, the VBox will first dispatch a touchOut. Then, the button will dispatch a touchOver which bubbles up to its parent. This approach causes a flickering effect as you move over the buttons.
Instead if you choose to listen for the touchRollOver/touchRollOut events, the VBox itself will dispatch a touchRollOver event when you move over the VBox. But no other events are dispatched when you move over the child buttons. Hence, there is no flickering effect and likely the smooth visual look you desire.
Gesture Events
- gesturePane – Dispatched when the user moves fingers across the device
- gesturePressAndTap – Dispatched when the user creates a point of contact on the device and then taps
- gestureRotate – Dispatched when the user performs a rotation gesture over a component
- gestureSwipe – Dispatched when the user swipes fingers across a component
- gestureTwoFingerTap – Dispatched when the user presses two points of contact over the same component
- gestureZoom – Dispatched when the user performs a pinching or stretching gesture over a component
The flash.ui.Multitouch
class and flash.ui.MultitouchInputMode
allows a developer to set whether touch events or gesture events are dispatched for touch-enabled devices. The Multitouch
class also allows the developer to interrogate which, if any, gestures, touch points and types of touch events and gesture events that are possible on the device.
Tighter Desktop Integration
Several new features allow you to develop applications that take advantage of even tighter integration with the desktop including automatic detection of mass storage devices, the ability to open files with the default application as it is associated in the operating system, the ability to access and manipulate a microphone and better cross-platform printing support.
Detection of mass storage devices
In recent years there has been a proliferation of devices that we can easily connect to our computers. The devices include phones, cameras, video cameras, portable hard drives and jump drives. These devices generally provide storage and often contain files such as documents, pictures, videos and music. We generally connect these devices to our computers to manipulate them with software that exists on our computers, print them or copy them to or from the device.
The flash.filesystem.StorageVolumeInfo
class provides a way to easily determine which storage volumes currently exist as well as dispatching events to notify listeners when additional volumes have been mounted or existing volumes unmounted.
The flash.filesystem.StorageVolume
represents each available mass storage device currently accessible on your computer and provides access to the drive (on Windows), file system type (i.e. FAT, NTFS, HFS, UFS), name and whether the volume is writable and removable. Most importantly, access is provided to the root directory in the form of a flash.filesystem.File
object. This means that an application can navigate, read, copy, write, delete or append any files on the volume as well as create/delete subdirectories.
Using another new feature in AIR 2.0, applications can also open any file with its default application, which is the perfect segue into the next feature.
Opening files with their default application
Users are familiar with clicking or double-clicking files to open them. Modern operating systems provide associations between file extensions/types and the applications that are responsible for opening them.
For example, .pdf files are generally opened by Adobe Acrobat Reader, .html files are opened by your default internet browser, .mp3 files are opened by your media player of choice as are all sorts of other media files including .jpg, .avi and .mp4. This capability is now provided by AIR 2.0 by using the flash.filesystem.File.openWithDefaultApplication()
function.
As a security precaution, file types that execute code such as script files cannot be opened by this new API, unless the application was installed by a native installer (see Native Code Integration above).
Access to the microphone
AIR has always provided support for accessing a camera/web camera for recording video or taking pictures and handling the resultant data from the device. However, access to the microphone was never supported, until now.
Like the flash.media.Camera
class, the new flash.media.Microphone
class provides access to a microphone and allows application developers to interrogate and set various properties. Most importantly, access to the audio stream is provided so that it can be saved or even played back.
After a reference to a microphone has been established, numerous properties can be interrogated and/or set including the frames per packet, gain, whether the microphone is muted, the noise suppression level, the recording rate (in kHz), the silence level and the codec used to compress the audio, among others.
Access to the audio stream is provided by listening for the sampleData event. Once the sound data is captured, it can be stored in a file for use later or played back immediately using the audio support that already exists.
Improved cross-platform printing support
Though Adobe AIR has always provided support for printing as well as some level of control over the print options, AIR 2.0 has added some classes to allow for better control over the process.
The flash.printing.PrintUIOptions
class provides a way for an application developer to specify exactly which print dialog options are editable by the user. These options include copies, orientation, page range, paper size, scaling and minimum and maximum page number. The developer can selectively enable or disable the ability for a user to edit these values when the platform print dialog is shown.
The flash.printing.PrintJob
was always the heavy lifter when it came to printing in AIR and the class has been changed in AIR 2.0 to use the new PrintUIOptions
class. To print to a printer, an application developer typically will follow a standard process:
- Create a
flash.printing.PrintJob
- Set the relevant properties on the print job (i.e. copies, orientation, page height, page width, printer, whether or not to print in color, etc)
- Invoke the
PrintJob.start()
function - Invoke
PrintJob.addPage()
for each page to be printed - Invoke
PrintJob.send()
to send the job to the printer
The PrintJob.start()
function would display the operating system's print dialog if the environment supported it, but there was no way to control which options on the dialog were editable and which were not. Further, the dialog would display always as long as the environment supported it.
AIR 2.0 provides more options to developers. PrintJob.start2()
accepts a flash.printing.PrintUIOptions
object (described earlier) and a boolean flag which suppresses the print dialog if set. I would have much rather seen a better function name than PrintJob.start2()
. I literally cannot wait for AIR 3.0 just to see if we have a new PrintJob.start3()
function. How about something like PrintJob.startWithOptions()
? Adobe is known for its creative products. Where is the creativity in a function name like that? C'mon, man! The good news is that AIR 2.0 is still in beta. Maybe they will change that function name before AIR 2.0 is released. For those Java programmers out there wondering why not just overload the start()
function, ActionScript 3 does not allow function overloading. This is an unfortunate omission from the language that would be very nice to have.
Screen Reader Support (Windows only)
For those developers that are developing accessible application, some enhancements have been made to support screen readers.
Runtime dialog boxes can be read, including those that displayed during the installation of an AIR application. Flex components and containers that a developer has made accessible can also be read by screen readers.
Database transaction savepoints
The SQLite database that comes with Adobe AIR and is accessible to AIR developers provides support for savepoints. Adobe AIR 2.0 now allows you to define and use savepoints within your transactions.
Savepoints provide a way to segment a complex database transaction consisting of numerous individual statements into smaller pieces. Savepoints can almost be thought of as a transaction within a transaction.
Savepoints can be used to rollback a transaction to a specific spot, attempt to change or recover something and then continue as opposed to rolling back an entire transaction.
The flash.data.SQLConnection
provides three new functions; SQLConnection.setSavepoint()
, SQLConnection.releaseSavepoint()
and SQLConnection.rollbackToSavepoint()
for working with savepoints.
File Promises
File Promises are a new feature of Adobe AIR that essentially allows developers to create references to files that do not yet exist and be able to pass them around and use them as if they do. At some point in the process, it is necessary to turn these file promises into actual files.
The typical use case for file promises and the most common demo you're likely to see involves dragging and dropping a list of files that exist on a remote server somewhere onto your desktop or into your application. In this scenario, the files don't yet actually exist yet so referring to them as flash.filesystem.File
objects will not work.
The flash.desktop.URLFilePromise
is a new class and an implementation of the flash.desktop.IFilePromise
interface which provides the basis for the whole concept of file promises. A developer can now write applications that treat these remote file references as real things by creating instances of the URLFilePromise
class. A simple drag and drop implementation is facilitated by adding an array of URLFilePromise
instances to the clipboard and specifying the clipboard data format as ClipboardFormat.FILE_PROMISE_LIST
. You can also add progress event listeners to the URLFilePromise
s and be notified of the download progress.
Since the whole concept behind the File Promises is to create references to files that don't yet exist, a developer can actually provide their own IFilePromise
implementation and generate files programmatically on demand.
Summary
The AIR 2.0 release contains lots of features that developers should find useful. I've given you a brief overview of most of the announced features. If you wish to learn more, I encourage you to visit Adobe Labs, download the SDK and begin experimenting with the new features. There are plenty of articles, blogs, documentation and videos with code samples to get you started.
If you have an existing AIR 1.x application, I strongly encourage you to download the new SDK beta now to make sure your application will run with AIR 2.0. Unless your users are enterprise users and your IT department controls the installation of new AIR runtimes, they will automatically begin downloading and installing the new runtime as soon as it is released by Adobe in a few months.