August 25, 2008 5:41 PM
AIR makes it possible to easily extend your Flex web application to
the desktop. Here, we discuss three ways to share code that is common
between your Flex and AIR application. Some ways are obvious and some
are not.
Common code in a library project
Create an ActionScript library project where all your common code is kept. Then you link in the SWC from both your Flex and AIR project. The AIR project will have AIR specific code plus all the stuff from the SWC.
You have to have a minimum of three Flex Builder projects for this method: A Flex Project, a Flex library project and an AIR project.
Interfaces
There's an excellent devnet article on this. This method takes advantage of the fact that the MXML compiler does not compile classes which are not directly referenced from your application. Your application should never directly reference a class that depends on AIR only API calls. Instead, depend on a factory class that will return an AIR or Flex specific implementation class depending on whether the code is being run in AIR or not.
You can always determine at runtime if you are within AIR or not by
checking Security.sandBoxType
. It will be application
when the code is
running in AIR.
For this method to work though, in your AIR and Flex project, you must declare an instance of the concrete implementation class. That is, your AIR project's main MXML file should have a var obj:AirImplementation and your Flex project should have a var obj:FlexImplementation declaration. This is what tells the compiler that the AIR project should compile in class AirImplementation. Since FlexImplementation is not referenced in the AIR project, it will not be compiled in.
This method only requires two projects: One AIR and one Flex project. Common code is added from one location to both the projects1.
Conditional Compilation
In ActionScript, you can conditionally compile parts of your code depending on whether a variable has been defined at compile time. This means if you create a AIR and Flex Project, add a source folder to it so that it reads the source code from the same place, pass different compile arguments to it, you can have the same codebase provide different functionality according to whether it is an AIR or Flex project.
The main advantage of this method is that without relying on any kind of interface class, your classes can neatly have AIR only properties / functions.
Consider SharedClass.as:
package com.foo.bar { public class SharedClass { public function SharedClass() { } public function getData():Number { return 0; } CONFIG::FLEX public function getLibFrom():String { return "Flex"; } CONFIG::AIR public function getLibFrom():String { return "AIR"; } CONFIG::AIR public function readFile():String { return "ReadFile"; } } }
Depending on the compiler arguments passed to mxmlc
, now
SharedClass can have the same function perform different things
or have additional functions. When run from AIR, getLibFrom()
will
return AIR while from Flex, it will return Flex. readFile()
is a
function that will only be available in the AIR project.
This is how the compiler argument2 for the Flex project looks like:
-define=CONFIG::FLEX,true -define=CONFIG::AIR,false
And for AIR:
-define=CONFIG::FLEX,false -define=CONFIG::AIR,true
More information about conditional compilation is available on livedocs.
This method only requires two projects: One AIR and one Flex project. Common code is added from one location to both the projects.
[1] Right click the flex project in Flex Builder and choose Properties
- Flex Build Path. In the "Source path" tab, click "Add Folder"
and point to the location of the common code.
[2] You can add compiler arguments by right clicking the project, properties, flex compiler, additional compiler arguments.